From bfda334497f598567b648b12e7aa9b1fd00e4cf2 Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Fri, 14 Sep 2018 09:42:33 -0300 Subject: [PATCH 001/142] Change "addPermission()" to "addDelegate()" --- .../PermissionManager/GeneralPermissionManager.sol | 10 +++++----- test/g_general_permission_manager.js | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 1550289ee..06daa39df 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -18,7 +18,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { /// Event emitted after any permission get changed for the delegate event LogChangePermission(address _delegate, address _module, bytes32 _perm, bool _valid, uint256 _timestamp); /// Use to notify when delegate is added in permission manager contract - event LogAddPermission(address _delegate, bytes32 _details, uint256 _timestamp); + event LogAddDelegate(address _delegate, bytes32 _details, uint256 _timestamp); /// @notice constructor constructor (address _securityToken, address _polyAddress) public @@ -35,7 +35,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { } /** - * @notice use to check the permission on delegate corresponds to module contract address + * @notice Use to check the permission on delegate corresponds to module contract address * @param _delegate Ethereum address of the delegate * @param _module Ethereum contract address of the module * @param _perm Permission flag @@ -49,13 +49,13 @@ contract GeneralPermissionManager is IPermissionManager, Module { } /** - * @notice use to add the details of the delegate + * @notice Use to add a delegate * @param _delegate Ethereum address of the delegate * @param _details Details about the delegate i.e `Belongs to financial firm` */ - function addPermission(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { + function addDelegate(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { delegateDetails[_delegate] = _details; - emit LogAddPermission(_delegate, _details, now); + emit LogAddDelegate(_delegate, _details, now); } /** diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index c5c47f789..3c37a00bd 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -359,10 +359,10 @@ contract('GeneralPermissionManager', accounts => { assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); }); - it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async() => { + it("Should fail in adding the delegate -- msg.sender doesn't have permission", async() => { let errorThrown = false; try { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1}); + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}); } catch(error) { console.log(` tx revert -> msg.sender doesn't have permission`.grey); errorThrown = true; @@ -371,7 +371,7 @@ contract('GeneralPermissionManager', accounts => { assert.ok(errorThrown, message); }); - it("Should fail to provide the permission-- because delegate is not yet added", async() => { + it("Should fail to provide the permission -- because delegate is not yet added", async() => { let errorThrown = false; try { let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); @@ -383,8 +383,8 @@ contract('GeneralPermissionManager', accounts => { assert.ok(errorThrown, message); }); - it("Should add the permission to the delegate", async() => { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); + it("Should successfuly add the delegate", async() => { + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate); }); From 0a7e17a9daa5fc8a0650a46f4e799f28cfc3b8a7 Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Fri, 14 Sep 2018 09:50:33 -0300 Subject: [PATCH 002/142] Remove "getDelegateDetails()" --- .../PermissionManager/GeneralPermissionManager.sol | 9 --------- .../modules/PermissionManager/IPermissionManager.sol | 2 -- test/g_general_permission_manager.js | 2 +- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 06daa39df..c2537de48 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -82,15 +82,6 @@ contract GeneralPermissionManager is IPermissionManager, Module { return true; } - /** - * @notice Use to get the details of the delegate - * @param _delegate Ethereum address of the delegate - * @return Details of the delegate - */ - function getDelegateDetails(address _delegate) external view returns(bytes32) { - return delegateDetails[_delegate]; - } - /** * @notice Use to get the Permission flag related the `this` contract * @return Array of permission flags diff --git a/contracts/modules/PermissionManager/IPermissionManager.sol b/contracts/modules/PermissionManager/IPermissionManager.sol index 4e88009d3..a893beee4 100644 --- a/contracts/modules/PermissionManager/IPermissionManager.sol +++ b/contracts/modules/PermissionManager/IPermissionManager.sol @@ -9,6 +9,4 @@ interface IPermissionManager { function changePermission(address _delegate, address _module, bytes32 _perm, bool _valid) external returns(bool); - function getDelegateDetails(address _delegate) external view returns(bytes32); - } diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 3c37a00bd..969516425 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -414,7 +414,7 @@ contract('GeneralPermissionManager', accounts => { }); it("Should check the delegate details", async() => { - assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)) + assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.delegateDetails.call(account_delegate)) .replace(/\u0000/g, ''), delegateDetails, "Wrong delegate address get checked"); From 34c8c19c8940dfc13baa0555bf1f22d1c052d1e5 Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Fri, 14 Sep 2018 10:00:32 -0300 Subject: [PATCH 003/142] Add requirement to avoid empty details on "addDelegate()" --- .../PermissionManager/GeneralPermissionManager.sol | 1 + test/g_general_permission_manager.js | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index c2537de48..7812c00f4 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -54,6 +54,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @param _details Details about the delegate i.e `Belongs to financial firm` */ function addDelegate(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { + require(_details != bytes32(0), "Delegate details not set"); delegateDetails[_delegate] = _details; emit LogAddDelegate(_delegate, _details, now); } diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 969516425..e2e4c1c18 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -371,6 +371,18 @@ contract('GeneralPermissionManager', accounts => { assert.ok(errorThrown, message); }); + it("Should fail in adding the delegate -- no delegate details provided", async() => { + let errorThrown = false; + try { + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: account_investor1}); + } catch(error) { + console.log(` tx revert -> delegate details were not provided`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + it("Should fail to provide the permission -- because delegate is not yet added", async() => { let errorThrown = false; try { From 3566d169c3463853b208fff36ab91544d27de8ff Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Fri, 14 Sep 2018 09:42:33 -0300 Subject: [PATCH 004/142] Change "addPermission()" to "addDelegate()" --- .../PermissionManager/GeneralPermissionManager.sol | 11 ++++++----- test/g_general_permission_manager.js | 10 +++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index c11806344..e2a4b98ee 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -18,7 +18,8 @@ contract GeneralPermissionManager is IPermissionManager, Module { /// Event emitted after any permission get changed for the delegate event ChangePermission(address _delegate, address _module, bytes32 _perm, bool _valid, uint256 _timestamp); /// Use to notify when delegate is added in permission manager contract - event AddPermission(address _delegate, bytes32 _details, uint256 _timestamp); + event LogAddDelegate(address _delegate, bytes32 _details, uint256 _timestamp); + /// @notice constructor constructor (address _securityToken, address _polyAddress) public @@ -35,7 +36,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { } /** - * @notice use to check the permission on delegate corresponds to module contract address + * @notice Use to check the permission on delegate corresponds to module contract address * @param _delegate Ethereum address of the delegate * @param _module Ethereum contract address of the module * @param _perm Permission flag @@ -49,13 +50,13 @@ contract GeneralPermissionManager is IPermissionManager, Module { } /** - * @notice use to add the details of the delegate + * @notice Use to add a delegate * @param _delegate Ethereum address of the delegate * @param _details Details about the delegate i.e `Belongs to financial firm` */ - function addPermission(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { + function addDelegate(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { delegateDetails[_delegate] = _details; - emit AddPermission(_delegate, _details, now); + emit LogAddDelegate(_delegate, _details, now); } /** diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 3b7299ca2..02482cffd 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -325,10 +325,10 @@ contract('GeneralPermissionManager', accounts => { assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); }); - it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async() => { + it("Should fail in adding the delegate -- msg.sender doesn't have permission", async() => { let errorThrown = false; try { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1}); + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}); } catch(error) { console.log(` tx revert -> msg.sender doesn't have permission`.grey); errorThrown = true; @@ -337,7 +337,7 @@ contract('GeneralPermissionManager', accounts => { assert.ok(errorThrown, message); }); - it("Should fail to provide the permission-- because delegate is not yet added", async() => { + it("Should fail to provide the permission -- because delegate is not yet added", async() => { let errorThrown = false; try { let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); @@ -349,8 +349,8 @@ contract('GeneralPermissionManager', accounts => { assert.ok(errorThrown, message); }); - it("Should add the permission to the delegate", async() => { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); + it("Should successfuly add the delegate", async() => { + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate); }); From 8612b2060c109e9282413a313a7c47721c29726e Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Fri, 14 Sep 2018 09:50:33 -0300 Subject: [PATCH 005/142] Remove "getDelegateDetails()" --- .../PermissionManager/GeneralPermissionManager.sol | 9 --------- .../modules/PermissionManager/IPermissionManager.sol | 2 -- test/g_general_permission_manager.js | 2 +- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index e2a4b98ee..f470e74d5 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -83,15 +83,6 @@ contract GeneralPermissionManager is IPermissionManager, Module { return true; } - /** - * @notice Use to get the details of the delegate - * @param _delegate Ethereum address of the delegate - * @return Details of the delegate - */ - function getDelegateDetails(address _delegate) external view returns(bytes32) { - return delegateDetails[_delegate]; - } - /** * @notice Use to get the Permission flag related the `this` contract * @return Array of permission flags diff --git a/contracts/modules/PermissionManager/IPermissionManager.sol b/contracts/modules/PermissionManager/IPermissionManager.sol index 4e88009d3..a893beee4 100644 --- a/contracts/modules/PermissionManager/IPermissionManager.sol +++ b/contracts/modules/PermissionManager/IPermissionManager.sol @@ -9,6 +9,4 @@ interface IPermissionManager { function changePermission(address _delegate, address _module, bytes32 _perm, bool _valid) external returns(bool); - function getDelegateDetails(address _delegate) external view returns(bytes32); - } diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 02482cffd..42217f960 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -380,7 +380,7 @@ contract('GeneralPermissionManager', accounts => { }); it("Should check the delegate details", async() => { - assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)) + assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.delegateDetails.call(account_delegate)) .replace(/\u0000/g, ''), delegateDetails, "Wrong delegate address get checked"); From 2b28b3ee26900ef7d0f1d4d71b5d3047ce862e24 Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Fri, 14 Sep 2018 10:00:32 -0300 Subject: [PATCH 006/142] Add requirement to avoid empty details on "addDelegate()" --- .../PermissionManager/GeneralPermissionManager.sol | 1 + test/g_general_permission_manager.js | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index f470e74d5..c4a458d0f 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -55,6 +55,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @param _details Details about the delegate i.e `Belongs to financial firm` */ function addDelegate(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { + require(_details != bytes32(0), "Delegate details not set"); delegateDetails[_delegate] = _details; emit LogAddDelegate(_delegate, _details, now); } diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 42217f960..cb8f0b1c9 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -337,6 +337,18 @@ contract('GeneralPermissionManager', accounts => { assert.ok(errorThrown, message); }); + it("Should fail in adding the delegate -- no delegate details provided", async() => { + let errorThrown = false; + try { + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: account_investor1}); + } catch(error) { + console.log(` tx revert -> delegate details were not provided`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + it("Should fail to provide the permission -- because delegate is not yet added", async() => { let errorThrown = false; try { From faf1bab2d3d0ff2da025e8d40395f940532dc89a Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Tue, 2 Oct 2018 16:23:06 +0200 Subject: [PATCH 007/142] generalPermissionManager changes --- .node-xmlhttprequest-content-39801 | 1 + .../GeneralPermissionManager.sol | 74 ++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 .node-xmlhttprequest-content-39801 diff --git a/.node-xmlhttprequest-content-39801 b/.node-xmlhttprequest-content-39801 new file mode 100644 index 000000000..451f07b26 --- /dev/null +++ b/.node-xmlhttprequest-content-39801 @@ -0,0 +1 @@ +{"err":{"errno":"ECONNREFUSED","code":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":8545}} \ No newline at end of file diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index c4a458d0f..ab4a06f1c 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -12,6 +12,10 @@ contract GeneralPermissionManager is IPermissionManager, Module { mapping (address => mapping (address => mapping (bytes32 => bool))) public perms; // Mapping hold the delagate details mapping (address => bytes32) public delegateDetails; + // Array to track all delegates + address[] public allDelegates; + + // Permission flag bytes32 public constant CHANGE_PERMISSION = "CHANGE_PERMISSION"; @@ -57,10 +61,11 @@ contract GeneralPermissionManager is IPermissionManager, Module { function addDelegate(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { require(_details != bytes32(0), "Delegate details not set"); delegateDetails[_delegate] = _details; + allDelegates.push(_delegate); emit LogAddDelegate(_delegate, _details, now); } - /** + /** * @notice Use to provide/change the permission to the delegate corresponds to the module contract * @param _delegate Ethereum address of the delegate * @param _module Ethereum contract address of the module @@ -94,4 +99,71 @@ contract GeneralPermissionManager is IPermissionManager, Module { return allPermissions; } + /** + * @notice use to get all delegates + * @return address[] + */ + function getAllDelegates() public view returns(address[]) { + return allDelegates; + } + + /** + * @notice use to check if an address is a delegate or not + * @param _potentialDelegate the address of potential delegate + * @return bool + */ + function isDelegate(address _potentialDelegate) public view returns(bool) { + if (delegateDetails[_potentialDelegate] != bytes32(0)) { + return true; + }else + return false; + } + + /** + * @notice Use to change one or more permissions for a single delegate at once + * @param _delegate Ethereum address of the delegate + * @param _module Ethereum contract address of the module + * @param _multiModule Multiple module matching the multiperms, needs to be same length + * @param _multiPerms Multiple permission flag needs to be changed + * @return nothing + */ + function changePermissionBulk( + address _delegate, + address[] _multiModules, + bytes32[] _multiPerms + ) + external + withPerm(CHANGE_PERMISSION) + { + require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); + + for(uint8 i=0;i<_multiPerms.length;i++){ + bool _currentPerm = !perms[_multiModules[i]][_delegate][_multiPerms[i]]; + perms[_multiModules[i]][_delegate][_multiPerms[i]] = _currentPerm; + emit LogChangePermission(_delegate, [_multiModules[i]], _multiPerms[i], _currentPerm, now); + } + } + + /** + * @notice use to return all delegates with a given permission and module + * @return address[] + */ + function getAllDelegatesWithPerm(_module, _perm) public view returns(address[]) { + + address[] memory allDelegatesWithPerm; + + for(uint8 i=0;i Date: Tue, 2 Oct 2018 21:34:13 +0100 Subject: [PATCH 008/142] WIP --- contracts/ModuleRegistry.sol | 25 ++-- contracts/interfaces/IModuleFactory.sol | 2 +- contracts/interfaces/ISecurityToken.sol | 6 - contracts/interfaces/ITokenBurner.sol | 10 -- contracts/mocks/MockFactory.sol | 12 +- contracts/mocks/MockTokenBurner.sol | 19 --- contracts/mocks/TestSTOFactory.sol | 14 +- .../modules/Burn/TrackedRedemptionFactory.sol | 14 +- .../ERC20DividendCheckpointFactory.sol | 16 +-- .../EtherDividendCheckpointFactory.sol | 16 +-- .../GeneralPermissionManagerFactory.sol | 16 +-- contracts/modules/STO/CappedSTOFactory.sol | 14 +- contracts/modules/STO/DummySTOFactory.sol | 14 +- contracts/modules/STO/PreSaleSTOFactory.sol | 14 +- contracts/modules/STO/USDTieredSTOFactory.sol | 16 +-- .../CountTransferManagerFactory.sol | 16 +-- .../GeneralTransferManagerFactory.sol | 14 +- .../ManualApprovalTransferManagerFactory.sol | 18 +-- .../PercentageTransferManagerFactory.sol | 16 +-- contracts/tokens/SecurityToken.sol | 127 +++++++++++------- 20 files changed, 198 insertions(+), 201 deletions(-) delete mode 100644 contracts/interfaces/ITokenBurner.sol delete mode 100644 contracts/mocks/MockTokenBurner.sol diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index f0249e2fd..30316cc4c 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -126,8 +126,8 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } else { require(getBool(Encoder.getKey('verified', _moduleFactory)), "ModuleFactory must be verified"); } - require(_isCompatibleModule(_moduleFactory, msg.sender), "Version should within the compatible range of ST"); - require(getUint(Encoder.getKey('registry',_moduleFactory)) != 0, "ModuleFactory type should not be 0"); + require(_isCompatibleModule(_moduleFactory, msg.sender), "Incompatable versions"); + require(getArrayUint(Encoder.getKey('registry',_moduleFactory)) != [], "ModuleFactory not registered"); pushArray(Encoder.getKey('reputation', _moduleFactory), msg.sender); emit ModuleUsed(_moduleFactory, msg.sender); } @@ -153,14 +153,16 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } else { require(msg.sender == getAddress(Encoder.getKey("owner")), "Only owner allowed to register modules"); } - require(getUint(Encoder.getKey('registry', _moduleFactory)) == 0, "Module factory should not be pre-registered"); + require(getArrayUint(Encoder.getKey('registry', _moduleFactory)) == [], "Module factory should not be pre-registered"); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); - uint8 moduleType = moduleFactory.getType(); - require(moduleType != 0, "Factory moduleType should not equal to 0"); - set(Encoder.getKey('registry', _moduleFactory), uint256(moduleType)); + uint8[] moduleTypes = moduleFactory.getTypes(); + for (uint256 i = 0; i < moduleTypes.length; i++) { + require(moduleTypes[i] != 0, "Factory moduleType should not equal to 0"); + pushArray(Encoder.getKey('registry', _moduleFactory), moduleTypes[i]); + } set(Encoder.getKey('moduleListIndex', _moduleFactory), uint256(getArrayAddress(Encoder.getKey('moduleList', uint256(moduleType))).length)); pushArray(Encoder.getKey('moduleList', uint256(moduleType)), _moduleFactory); - emit ModuleRegistered (_moduleFactory, IOwnable(_moduleFactory).owner()); + emit ModuleRegistered(_moduleFactory, IOwnable(_moduleFactory).owner()); } /** @@ -168,9 +170,8 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @param _moduleFactory is the address of the module factory to be deleted from the registry */ function removeModule(address _moduleFactory) external whenNotPausedOrOwner { - uint256 moduleType = getUint(Encoder.getKey('registry', _moduleFactory)); - - require(moduleType != 0, "Module factory should be registered"); + uint8[] moduleTypes = getArrayUint(Encoder.getKey('registry', _moduleFactory)); + require(moduleTypes != [], "Module factory not registered"); require(msg.sender == IOwnable(_moduleFactory).owner() || msg.sender == getAddress(Encoder.getKey('owner')), "msg.sender must be the Module Factory owner or registry curator"); @@ -187,7 +188,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { deleteArrayAddress(Encoder.getKey('moduleList', moduleType), last); // delete registry[_moduleFactory]; - set(Encoder.getKey('registry', _moduleFactory), uint256(0)); + setArray(Encoder.getKey('registry', _moduleFactory), []); // delete reputation[_moduleFactory]; setArray(Encoder.getKey('reputation', _moduleFactory), new address[](0)); // delete verified[_moduleFactory]; @@ -206,7 +207,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return bool */ function verifyModule(address _moduleFactory, bool _verified) external onlyOwner { - require(getUint(Encoder.getKey('registry', _moduleFactory)) != uint256(0), "Module factory must be registered"); + require(getUint(Encoder.getKey('registry', _moduleFactory)) != [], "Module factory must be registered"); set(Encoder.getKey('verified', _moduleFactory), _verified); emit ModuleVerified(_moduleFactory, _verified); } diff --git a/contracts/interfaces/IModuleFactory.sol b/contracts/interfaces/IModuleFactory.sol index 38f2a9e0d..839bb26ed 100644 --- a/contracts/interfaces/IModuleFactory.sol +++ b/contracts/interfaces/IModuleFactory.sol @@ -24,7 +24,7 @@ interface IModuleFactory { /** * @notice Type of the Module factory */ - function getType() external view returns(uint8); + function getTypes() external view returns(uint8[]); /** * @notice Get the name of the Module diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index c36f45270..ced158b9c 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -180,12 +180,6 @@ interface ISecurityToken { */ function mintMulti(address[] _investors, uint256[] _values) external returns (bool success); - /** - * @notice used to set the token Burner address. It can only be called by the owner - * @param _tokenBurner Address of the token burner contract - */ - function setTokenBurner(address _tokenBurner) external; - /** * @notice Removes a module attached to the SecurityToken * @param _module address of module to archive diff --git a/contracts/interfaces/ITokenBurner.sol b/contracts/interfaces/ITokenBurner.sol deleted file mode 100644 index bf5ca0819..000000000 --- a/contracts/interfaces/ITokenBurner.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma solidity ^0.4.24; - -/** - * @title Interface for the token burner contract - */ -interface ITokenBurner { - - function burn(address _burner, uint256 _value ) external returns(bool); - -} diff --git a/contracts/mocks/MockFactory.sol b/contracts/mocks/MockFactory.sol index 2f7772d77..90e64235d 100644 --- a/contracts/mocks/MockFactory.sol +++ b/contracts/mocks/MockFactory.sol @@ -40,8 +40,8 @@ contract MockFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 0; + function getTypes() external view returns(uint8[]) { + return [0]; } /** @@ -54,14 +54,14 @@ contract MockFactory is ModuleFactory { /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -82,14 +82,14 @@ contract MockFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Mock Manager - This is mock in nature"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](4); availableTags[0] = "Mock"; return availableTags; diff --git a/contracts/mocks/MockTokenBurner.sol b/contracts/mocks/MockTokenBurner.sol deleted file mode 100644 index cd5c4be23..000000000 --- a/contracts/mocks/MockTokenBurner.sol +++ /dev/null @@ -1,19 +0,0 @@ -pragma solidity ^0.4.24; - -import "../interfaces/ITokenBurner.sol"; - -contract MockTokenBurner is ITokenBurner { - - address public securityToken; - - constructor (address _securityToken) public { - securityToken = _securityToken; - } - - function burn(address /* _burner */, uint256 /* _value */) public view returns(bool) { - require(msg.sender == securityToken); - // Add the schematics for the burner( token holder) that backing the burning of the securities - return true; - } - -} diff --git a/contracts/mocks/TestSTOFactory.sol b/contracts/mocks/TestSTOFactory.sol index 71521e242..89540d1c1 100644 --- a/contracts/mocks/TestSTOFactory.sol +++ b/contracts/mocks/TestSTOFactory.sol @@ -40,28 +40,28 @@ contract TestSTOFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 3; + function getTypes() external view returns(uint8[]) { + return [3]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -82,14 +82,14 @@ contract TestSTOFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Test STO - you can mint tokens at will"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](4); availableTags[0] = "Test"; availableTags[1] = "Non-refundable"; diff --git a/contracts/modules/Burn/TrackedRedemptionFactory.sol b/contracts/modules/Burn/TrackedRedemptionFactory.sol index 94003286b..99907f977 100644 --- a/contracts/modules/Burn/TrackedRedemptionFactory.sol +++ b/contracts/modules/Burn/TrackedRedemptionFactory.sol @@ -41,21 +41,21 @@ contract TrackedRedemptionFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 5; + function getTypes() external view returns(uint8[]) { + return [5]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } @@ -69,7 +69,7 @@ contract TrackedRedemptionFactory is ModuleFactory { /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -83,14 +83,14 @@ contract TrackedRedemptionFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Allows an investor to redeem security tokens which are tracked by this module"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](2); availableTags[0] = "Redemption"; availableTags[1] = "Tracked"; diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol index d789ad5e3..f978725f8 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol @@ -17,7 +17,7 @@ contract ERC20DividendCheckpointFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { version = "1.0.0"; name = "ERC20DividendCheckpoint"; title = "ERC20 Dividend Checkpoint"; @@ -41,28 +41,28 @@ contract ERC20DividendCheckpointFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 4; + function getTypes() external view returns(uint8[]) { + return [4]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -83,14 +83,14 @@ contract ERC20DividendCheckpointFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](3); availableTags[0] = "ERC20"; availableTags[1] = "Dividend"; diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol index 146691d82..76d3a9f12 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol @@ -17,7 +17,7 @@ contract EtherDividendCheckpointFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { version = "1.0.0"; name = "EtherDividendCheckpoint"; title = "Ether Dividend Checkpoint"; @@ -41,28 +41,28 @@ contract EtherDividendCheckpointFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 4; + function getTypse() external view returns(uint8[]) { + return [4]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -83,14 +83,14 @@ contract EtherDividendCheckpointFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](3); availableTags[0] = "ETH"; availableTags[1] = "Checkpoint"; diff --git a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol index e6e6e65a1..67d0b7df8 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol @@ -14,7 +14,7 @@ contract GeneralPermissionManagerFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { version = "1.0.0"; name = "GeneralPermissionManager"; title = "General Permission Manager"; @@ -38,28 +38,28 @@ contract GeneralPermissionManagerFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 1; + function getTypes() external view returns(uint8[]) { + return [1]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -80,14 +80,14 @@ contract GeneralPermissionManagerFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required."; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](0); return availableTags; } diff --git a/contracts/modules/STO/CappedSTOFactory.sol b/contracts/modules/STO/CappedSTOFactory.sol index 982f790f0..6b75612a0 100644 --- a/contracts/modules/STO/CappedSTOFactory.sol +++ b/contracts/modules/STO/CappedSTOFactory.sol @@ -43,28 +43,28 @@ contract CappedSTOFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 3; + function getTypes() external view returns(uint8[]) { + return [3]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -85,14 +85,14 @@ contract CappedSTOFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](4); availableTags[0] = "Capped"; availableTags[1] = "Non-refundable"; diff --git a/contracts/modules/STO/DummySTOFactory.sol b/contracts/modules/STO/DummySTOFactory.sol index ec249b420..137cf6b6d 100644 --- a/contracts/modules/STO/DummySTOFactory.sol +++ b/contracts/modules/STO/DummySTOFactory.sol @@ -42,28 +42,28 @@ contract DummySTOFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 3; + function getTypes() external view returns(uint8[]) { + return [3]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -84,14 +84,14 @@ contract DummySTOFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Dummy STO - you can mint tokens at will"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](4); availableTags[0] = "Dummy"; availableTags[1] = "Non-refundable"; diff --git a/contracts/modules/STO/PreSaleSTOFactory.sol b/contracts/modules/STO/PreSaleSTOFactory.sol index 03ca13bbe..223392669 100644 --- a/contracts/modules/STO/PreSaleSTOFactory.sol +++ b/contracts/modules/STO/PreSaleSTOFactory.sol @@ -45,28 +45,28 @@ contract PreSaleSTOFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 3; + function getTypes() external view returns(uint8[]) { + return [3]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -87,14 +87,14 @@ contract PreSaleSTOFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Configure and track pre-sale token allocations"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](1); availableTags[0] = "Presale"; return availableTags; diff --git a/contracts/modules/STO/USDTieredSTOFactory.sol b/contracts/modules/STO/USDTieredSTOFactory.sol index 1b01cec66..4f9d772f0 100644 --- a/contracts/modules/STO/USDTieredSTOFactory.sol +++ b/contracts/modules/STO/USDTieredSTOFactory.sol @@ -17,7 +17,7 @@ contract USDTieredSTOFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost, address _proxyFactoryAddress) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { require(_proxyFactoryAddress != address(0), "0x address is not allowed"); USDTieredSTOProxyAddress = _proxyFactoryAddress; version = "1.0.0"; @@ -49,28 +49,28 @@ contract USDTieredSTOFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 3; + function getTypes() external view returns(uint8[]) { + return [3]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -91,14 +91,14 @@ contract USDTieredSTOFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Initialises a USD tiered STO."; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](4); availableTags[0] = "USD"; availableTags[1] = "Tiered"; diff --git a/contracts/modules/TransferManager/CountTransferManagerFactory.sol b/contracts/modules/TransferManager/CountTransferManagerFactory.sol index aa7d2cda2..43acf38a6 100644 --- a/contracts/modules/TransferManager/CountTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/CountTransferManagerFactory.sol @@ -15,7 +15,7 @@ contract CountTransferManagerFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { version = "1.0.0"; name = "CountTransferManager"; title = "Count Transfer Manager"; @@ -43,28 +43,28 @@ contract CountTransferManagerFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 2; + function getTypes() external view returns(uint8[]) { + return [2]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -85,14 +85,14 @@ contract CountTransferManagerFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Allows an issuer to restrict the total number of non-zero token holders"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](2); availableTags[0] = "Count"; availableTags[1] = "Transfer Restriction"; diff --git a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol index a3490130b..8ca244340 100644 --- a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol @@ -14,7 +14,7 @@ contract GeneralTransferManagerFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { version = "1.0.0"; name = "GeneralTransferManager"; title = "General Transfer Manager"; @@ -40,21 +40,21 @@ contract GeneralTransferManagerFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 2; + function getTypes() external view returns(uint8[]) { + return [2]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } @@ -68,7 +68,7 @@ contract GeneralTransferManagerFactory is ModuleFactory { /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -82,7 +82,7 @@ contract GeneralTransferManagerFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters."; } diff --git a/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol b/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol index 2c0e60eb5..ddc026042 100644 --- a/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol @@ -17,7 +17,7 @@ contract ManualApprovalTransferManagerFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { version = "1.0.0"; name = "ManualApprovalTransferManager"; title = "Manual Approval Transfer Manager"; @@ -41,31 +41,31 @@ contract ManualApprovalTransferManagerFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 2; + function getTypes() external view returns(uint8[]) { + return [2]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } - + /** * @notice Get the version of the Module */ @@ -83,14 +83,14 @@ contract ManualApprovalTransferManagerFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters."; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](2); availableTags[0] = "ManualApproval"; availableTags[1] = "Transfer Restriction"; diff --git a/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol b/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol index 59949880c..80ae0bd05 100644 --- a/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol @@ -15,7 +15,7 @@ contract PercentageTransferManagerFactory is ModuleFactory { */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { + { version = "1.0.0"; name = "PercentageTransferManager"; title = "Percentage Transfer Manager"; @@ -44,28 +44,28 @@ contract PercentageTransferManagerFactory is ModuleFactory { * @notice Type of the Module factory * @return uint8 */ - function getType() public view returns(uint8) { - return 2; + function getTypes() external view returns(uint8[]) { + return [2]; } /** * @notice Get the name of the Module */ - function getName() public view returns(bytes32) { + function getName() external view returns(bytes32) { return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { + function getDescription() external view returns(string) { return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { + function getTitle() external view returns(string) { return title; } @@ -86,14 +86,14 @@ contract PercentageTransferManagerFactory is ModuleFactory { /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { + function getInstructions() external view returns(string) { return "Allows an issuer to restrict the total number of non-zero token holders"; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](2); availableTags[0] = "Percentage"; availableTags[1] = "Transfer Restriction"; diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index c3d8ca8fb..655625b71 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -39,8 +39,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // off-chain hash string public tokenDetails; - uint8 public constant PERMISSIONMANAGER_KEY = 1; - uint8 public constant TRANSFERMANAGER_KEY = 2; + uint8 public constant PERMISSION_KEY = 1; + uint8 public constant TRANSFER_KEY = 2; uint8 public constant MINT_KEY = 3; uint8 public constant CHECKPOINT_KEY = 4; uint8 public constant BURN_KEY = 5; @@ -68,40 +68,49 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // address whitelisted by issuer as controller address public controller; + // Struct for module data struct ModuleData { bytes32 name; address module; address moduleFactory; bool isArchived; - uint8 moduleType; - uint256 moduleIndex; + uint8[] moduleTypes; + uint256[] moduleIndexes; uint256 nameIndex; + mapping (uint8 => bool) moduleType; + mapping (uint8 => uint256) moduleIndex; } + // Records added modules - module list should be order agnostic! + mapping (uint8 => address[]) public modules; + + // Records information about the module + mapping (address => ModuleData) modulesToData; + + // Records added module names - module list should be order agnostic! + mapping (bytes32 => address[]) names; + // Structures to maintain checkpoints of balances for governance / dividends struct Checkpoint { uint256 checkpointId; uint256 value; } + // Map each investor to a series of checkpoints mapping (address => Checkpoint[]) public checkpointBalances; - Checkpoint[] public checkpointTotalSupply; - uint256[] public checkpointTimes; - - // Records added modules - module list should be order agnostic! - mapping (uint8 => address[]) public modules; - // Records information about the module - mapping (address => ModuleData) modulesToData; + // List of checkpoints that relate to total supply + Checkpoint[] public checkpointTotalSupply; - // Records added module names - module list should be order agnostic! - mapping (bytes32 => address[]) names; + // Times at which each checkpoint was created + uint256[] public checkpointTimes; + // List of investors (may not be pruned to remove old investors with current zero balances) mapping (address => bool) public investorListed; // Emit at the time when module get added event ModuleAdded( - uint8 indexed _type, + uint8[] indexed _types, bytes32 _name, address _moduleFactory, address _module, @@ -115,13 +124,13 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // Emit when the granularity get changed event GranularityChanged(uint256 _oldGranularity, uint256 _newGranularity); // Emit when Module get removed from the securityToken - event ModuleRemoved(uint8 indexed _type, address _module, uint256 _timestamp); + event ModuleRemoved(uint8[] indexed _types, address _module, uint256 _timestamp); // Emit when Module get archived from the securityToken - event ModuleArchived(uint8 indexed _type, address _module, uint256 _timestamp); + event ModuleArchived(uint8[] indexed _types, address _module, uint256 _timestamp); // Emit when Module get unarchived from the securityToken - event ModuleUnarchived(uint8 indexed _type, address _module, uint256 _timestamp); + event ModuleUnarchived(uint8[] indexed _types, address _module, uint256 _timestamp); // Emit when the budget allocated to a module is changed - event ModuleBudgetChanged(uint8 indexed _moduleType, address _module, uint256 _oldBudget, uint256 _budget); + event ModuleBudgetChanged(uint8[] indexed _moduleTypes, address _module, uint256 _oldBudget, uint256 _budget); // Emit when transfers are frozen or unfrozen event FreezeTransfers(bool _status, uint256 _timestamp); // Emit when new checkpoint created @@ -142,7 +151,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr function isModule(address _module, uint8 _type) internal view returns (bool) { require(modulesToData[_module].module == _module, "Address mismatch"); - require(modulesToData[_module].moduleType == _type, "Type mismatch"); + require(modulesToData[_module].moduleType[_type], "Type mismatch"); require(!modulesToData[_module].isArchived, "Module archived"); return true; } @@ -246,7 +255,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr //Check that module exists in registry - will throw otherwise IModuleRegistry(moduleRegistry).useModule(_moduleFactory); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); - uint8 moduleType = moduleFactory.getType(); + uint8[] memory moduleTypes = moduleFactory.getTypes(); /* require(modules[moduleType].length < MAX_MODULES, "Limit of MAX MODULES is reached"); */ uint256 moduleCost = moduleFactory.getSetupCost(); require(moduleCost <= _maxCost, "Module cost too high"); @@ -259,11 +268,25 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr require(ERC20(polyToken).approve(module, _budget), "Insufficient funds for budget"); //Add to SecurityToken module map bytes32 moduleName = moduleFactory.getName(); - modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleType, modules[moduleType].length, names[moduleName].length); - modules[moduleType].push(module); + uint256[] memory moduleIndexes = new uint256[](moduleTypes.length); + //TODO: Enforce uniqueness + uint256 i; + uint256 j; + for (i = 0; i < moduleTypes.length; i++) { + for (j = i; j < moduleTypes.length; j++) { + require(moduleTypes[i] != moduleTypes[j], "Bad types"); + } + } + for (i = 0; i < moduleTypes.length; i++) { + moduleIndexes[i] = modules[moduleTypes[i]].length; + } + modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); + for (i = 0; i < moduleTypes.length; i++) { + modules[moduleTypes[i]].push(module); + } names[moduleName].push(module); //Emit log event - emit ModuleAdded(moduleType, moduleName, _moduleFactory, module, moduleCost, _budget, now); + emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, now); } /** @@ -273,7 +296,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr function archiveModule(address _module) external onlyOwner { require(!modulesToData[_module].isArchived, "Module already archived"); require(modulesToData[_module].module != address(0), "Module missing"); - emit ModuleArchived(modulesToData[_module].moduleType, _module, now); + emit ModuleArchived(modulesToData[_module].moduleTypes, _module, now); modulesToData[_module].isArchived = true; } @@ -283,10 +306,26 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function unarchiveModule(address _module) external onlyOwner { require(modulesToData[_module].isArchived, "Module already unarchived"); - emit ModuleUnarchived(modulesToData[_module].moduleType, _module, now); + emit ModuleUnarchived(modulesToData[_module].moduleTypes, _module, now); modulesToData[_module].isArchived = false; } + function _removeModuleWithIndex(uint8 _type, uint256 _index) internal { + uint256 length = modules[_type].length; + modules[_type][_index] = modules[_type][length - 1]; + modules[_type].length = length - 1; + + if ((length - 1) != _index) { + //Need to find index of _type in moduleTypes of module we are moving + uint8[] memory newTypes = modulesToData[modules[_type][_index]].moduleTypes; + for (uint256 i = 0; i < newTypes.length; i++) { + if (newTypes[i] == _type) { + modulesToData[modules[_type][_index]].moduleIndexes[i] = _index; + } + } + } + } + /** * @notice Removes a module attached to the SecurityToken * @param _module address of module to unarchive @@ -294,18 +333,15 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr function removeModule(address _module) external onlyOwner { require(modulesToData[_module].isArchived, "Module not archived"); require(modulesToData[_module].module != address(0), "Module missing"); - emit ModuleRemoved(modulesToData[_module].moduleType, _module, now); + emit ModuleRemoved(modulesToData[_module].moduleTypes, _module, now); // Remove from module type list - uint256 index = modulesToData[_module].moduleIndex; - uint8 moduleType = modulesToData[_module].moduleType; - uint256 length = modules[moduleType].length; - modules[moduleType][index] = modules[moduleType][length - 1]; - modules[moduleType].length = length - 1; - if ((length - 1) != index) { - modulesToData[modules[moduleType][index]].moduleIndex = index; + uint8[] moduleTypes = modulesToData[_module].moduleTypes; + for (uint256 i = 0; i < moduleTypes.length; i++) { + _removeModuleWithIndex(moduleTypes[i], modulesToData[_module].moduleIndexes[i]); } + // Remove from module names list - index = modulesToData[_module].nameIndex; + uint256 index = modulesToData[_module].nameIndex; bytes32 name = modulesToData[_module].name; length = names[name].length; names[name][index] = names[name][length - 1]; @@ -325,18 +361,13 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return address module factory address * @return bool module archived * @return uint8 module type - * @return uint256 module index - * @return uint256 name index - */ - function getModule(address _module) external view returns (bytes32, address, address, bool, uint8, uint256, uint256) { + function getModule(address _module) external view returns (bytes32, address, address, bool, uint8[]) { return (modulesToData[_module].name, modulesToData[_module].module, modulesToData[_module].moduleFactory, modulesToData[_module].isArchived, - modulesToData[_module].moduleType, - modulesToData[_module].moduleIndex, - modulesToData[_module].nameIndex); + modulesToData[_module].moduleTypes, } /** @@ -379,7 +410,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } else { require(IERC20(polyToken).increaseApproval(_module, _budget.sub(_currentAllowance)), "Insufficient balance to increaseApproval"); } - emit ModuleBudgetChanged(modulesToData[_module].moduleType, _module, _currentAllowance, _budget); + emit ModuleBudgetChanged(modulesToData[_module].moduleTypes, _module, _currentAllowance, _budget); } /** @@ -561,7 +592,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function _verifyTransfer(address _from, address _to, uint256 _value, bool _isTransfer) internal checkGranularity(_value) returns (bool) { if (!transfersFrozen) { - if (modules[TRANSFERMANAGER_KEY].length == 0) { + if (modules[TRANSFER_KEY].length == 0) { return true; } bool isInvalid = false; @@ -569,8 +600,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr bool isForceValid = false; bool unarchived = false; address module; - for (uint8 i = 0; i < modules[TRANSFERMANAGER_KEY].length; i++) { - module = modules[TRANSFERMANAGER_KEY][i]; + for (uint8 i = 0; i < modules[TRANSFER_KEY].length; i++) { + module = modules[TRANSFER_KEY][i]; if (!modulesToData[module].isArchived) { unarchived = true; ITransferManager.Result valid = ITransferManager(module).verifyTransfer(_from, _to, _value, _isTransfer); @@ -701,12 +732,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return success */ function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) { - if (modules[PERMISSIONMANAGER_KEY].length == 0) { + if (modules[PERMISSION_KEY].length == 0) { return false; } - for (uint8 i = 0; i < modules[PERMISSIONMANAGER_KEY].length; i++) { - if (IPermissionManager(modules[PERMISSIONMANAGER_KEY][i]).checkPermission(_delegate, _module, _perm)) { + for (uint8 i = 0; i < modules[PERMISSION_KEY].length; i++) { + if (IPermissionManager(modules[PERMISSION_KEY][i]).checkPermission(_delegate, _module, _perm)) { return true; } } From a925a8c682b09b7d5d1d80b9978a43b5d863f2db Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Tue, 2 Oct 2018 21:59:18 +0100 Subject: [PATCH 009/142] Fixes --- contracts/ModuleRegistry.sol | 26 +++++++++---------- contracts/mocks/MockFactory.sol | 4 ++- contracts/mocks/TestSTOFactory.sol | 4 ++- .../modules/Burn/TrackedRedemptionFactory.sol | 6 +++-- .../ERC20DividendCheckpointFactory.sol | 6 +++-- .../EtherDividendCheckpointFactory.sol | 8 +++--- .../GeneralPermissionManagerFactory.sol | 6 +++-- contracts/modules/STO/CappedSTOFactory.sol | 6 +++-- contracts/modules/STO/DummySTOFactory.sol | 6 +++-- contracts/modules/STO/PreSaleSTOFactory.sol | 6 +++-- contracts/modules/STO/USDTieredSTOFactory.sol | 6 +++-- .../CountTransferManagerFactory.sol | 6 +++-- .../GeneralTransferManagerFactory.sol | 6 +++-- .../ManualApprovalTransferManagerFactory.sol | 6 +++-- .../PercentageTransferManagerFactory.sol | 6 +++-- contracts/tokens/SecurityToken.sol | 9 +++---- 16 files changed, 72 insertions(+), 45 deletions(-) diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index 30316cc4c..60e5478a4 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -126,8 +126,8 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } else { require(getBool(Encoder.getKey('verified', _moduleFactory)), "ModuleFactory must be verified"); } - require(_isCompatibleModule(_moduleFactory, msg.sender), "Incompatable versions"); - require(getArrayUint(Encoder.getKey('registry',_moduleFactory)) != [], "ModuleFactory not registered"); + require(_isCompatibleModule(_moduleFactory, msg.sender), "Version should within the compatible range of ST"); + require(getUint(Encoder.getKey('registry',_moduleFactory)) != 0, "ModuleFactory type should not be 0"); pushArray(Encoder.getKey('reputation', _moduleFactory), msg.sender); emit ModuleUsed(_moduleFactory, msg.sender); } @@ -153,16 +153,15 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } else { require(msg.sender == getAddress(Encoder.getKey("owner")), "Only owner allowed to register modules"); } - require(getArrayUint(Encoder.getKey('registry', _moduleFactory)) == [], "Module factory should not be pre-registered"); + require(getUint(Encoder.getKey('registry', _moduleFactory)) == 0, "Module factory should not be pre-registered"); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); - uint8[] moduleTypes = moduleFactory.getTypes(); - for (uint256 i = 0; i < moduleTypes.length; i++) { - require(moduleTypes[i] != 0, "Factory moduleType should not equal to 0"); - pushArray(Encoder.getKey('registry', _moduleFactory), moduleTypes[i]); - } + require(moduleFactory.getTypes().length != 0, "Factory must have type"); + // NB - here we index by the first type of the module. + uint8 moduleType = moduleFactory.getTypes()[0]; + set(Encoder.getKey('registry', _moduleFactory), uint256(moduleType)); set(Encoder.getKey('moduleListIndex', _moduleFactory), uint256(getArrayAddress(Encoder.getKey('moduleList', uint256(moduleType))).length)); pushArray(Encoder.getKey('moduleList', uint256(moduleType)), _moduleFactory); - emit ModuleRegistered(_moduleFactory, IOwnable(_moduleFactory).owner()); + emit ModuleRegistered (_moduleFactory, IOwnable(_moduleFactory).owner()); } /** @@ -170,8 +169,9 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @param _moduleFactory is the address of the module factory to be deleted from the registry */ function removeModule(address _moduleFactory) external whenNotPausedOrOwner { - uint8[] moduleTypes = getArrayUint(Encoder.getKey('registry', _moduleFactory)); - require(moduleTypes != [], "Module factory not registered"); + uint256 moduleType = getUint(Encoder.getKey('registry', _moduleFactory)); + + require(moduleType != 0, "Module factory should be registered"); require(msg.sender == IOwnable(_moduleFactory).owner() || msg.sender == getAddress(Encoder.getKey('owner')), "msg.sender must be the Module Factory owner or registry curator"); @@ -188,7 +188,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { deleteArrayAddress(Encoder.getKey('moduleList', moduleType), last); // delete registry[_moduleFactory]; - setArray(Encoder.getKey('registry', _moduleFactory), []); + set(Encoder.getKey('registry', _moduleFactory), uint256(0)); // delete reputation[_moduleFactory]; setArray(Encoder.getKey('reputation', _moduleFactory), new address[](0)); // delete verified[_moduleFactory]; @@ -207,7 +207,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return bool */ function verifyModule(address _moduleFactory, bool _verified) external onlyOwner { - require(getUint(Encoder.getKey('registry', _moduleFactory)) != [], "Module factory must be registered"); + require(getUint(Encoder.getKey('registry', _moduleFactory)) != uint256(0), "Module factory must be registered"); set(Encoder.getKey('verified', _moduleFactory), _verified); emit ModuleVerified(_moduleFactory, _verified); } diff --git a/contracts/mocks/MockFactory.sol b/contracts/mocks/MockFactory.sol index 90e64235d..ba1f38083 100644 --- a/contracts/mocks/MockFactory.sol +++ b/contracts/mocks/MockFactory.sol @@ -41,7 +41,9 @@ contract MockFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [0]; + uint8[] memory res = new uint8[](1); + res[0] = 0; + return res; } /** diff --git a/contracts/mocks/TestSTOFactory.sol b/contracts/mocks/TestSTOFactory.sol index 89540d1c1..71517dcb8 100644 --- a/contracts/mocks/TestSTOFactory.sol +++ b/contracts/mocks/TestSTOFactory.sol @@ -41,7 +41,9 @@ contract TestSTOFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [3]; + uint8[] memory res = new uint8[](1); + res[0] = 3; + return res; } /** diff --git a/contracts/modules/Burn/TrackedRedemptionFactory.sol b/contracts/modules/Burn/TrackedRedemptionFactory.sol index 99907f977..6611b2875 100644 --- a/contracts/modules/Burn/TrackedRedemptionFactory.sol +++ b/contracts/modules/Burn/TrackedRedemptionFactory.sol @@ -42,13 +42,15 @@ contract TrackedRedemptionFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [5]; + uint8[] memory res = new uint8[](1); + res[0] = 5; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol index f978725f8..8d3644510 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol @@ -42,13 +42,15 @@ contract ERC20DividendCheckpointFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [4]; + uint8[] memory res = new uint8[](1); + res[0] = 4; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol index 76d3a9f12..487af022b 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol @@ -41,14 +41,16 @@ contract EtherDividendCheckpointFactory is ModuleFactory { /** * @notice Type of the Module factory */ - function getTypse() external view returns(uint8[]) { - return [4]; + function getTypes() external view returns(uint8[]) { + uint8[] memory res = new uint8[](1); + res[0] = 4; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol index 67d0b7df8..078f408dc 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol @@ -39,13 +39,15 @@ contract GeneralPermissionManagerFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [1]; + uint8[] memory res = new uint8[](1); + res[0] = 1; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/STO/CappedSTOFactory.sol b/contracts/modules/STO/CappedSTOFactory.sol index 6b75612a0..3c3597957 100644 --- a/contracts/modules/STO/CappedSTOFactory.sol +++ b/contracts/modules/STO/CappedSTOFactory.sol @@ -44,13 +44,15 @@ contract CappedSTOFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [3]; + uint8[] memory res = new uint8[](1); + res[0] = 3; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/STO/DummySTOFactory.sol b/contracts/modules/STO/DummySTOFactory.sol index 137cf6b6d..e4ddb8136 100644 --- a/contracts/modules/STO/DummySTOFactory.sol +++ b/contracts/modules/STO/DummySTOFactory.sol @@ -43,13 +43,15 @@ contract DummySTOFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [3]; + uint8[] memory res = new uint8[](1); + res[0] = 3; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/STO/PreSaleSTOFactory.sol b/contracts/modules/STO/PreSaleSTOFactory.sol index 223392669..a939fce19 100644 --- a/contracts/modules/STO/PreSaleSTOFactory.sol +++ b/contracts/modules/STO/PreSaleSTOFactory.sol @@ -46,13 +46,15 @@ contract PreSaleSTOFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [3]; + uint8[] memory res = new uint8[](1); + res[0] = 3; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/STO/USDTieredSTOFactory.sol b/contracts/modules/STO/USDTieredSTOFactory.sol index 4f9d772f0..e5a459f73 100644 --- a/contracts/modules/STO/USDTieredSTOFactory.sol +++ b/contracts/modules/STO/USDTieredSTOFactory.sol @@ -50,13 +50,15 @@ contract USDTieredSTOFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [3]; + uint8[] memory res = new uint8[](1); + res[0] = 3; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/TransferManager/CountTransferManagerFactory.sol b/contracts/modules/TransferManager/CountTransferManagerFactory.sol index 43acf38a6..1fe47a853 100644 --- a/contracts/modules/TransferManager/CountTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/CountTransferManagerFactory.sol @@ -44,13 +44,15 @@ contract CountTransferManagerFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [2]; + uint8[] memory res = new uint8[](1); + res[0] = 2; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol index 8ca244340..60e85f8f4 100644 --- a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol @@ -41,13 +41,15 @@ contract GeneralTransferManagerFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [2]; + uint8[] memory res = new uint8[](1); + res[0] = 2; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol b/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol index ddc026042..e3ad15901 100644 --- a/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol @@ -42,13 +42,15 @@ contract ManualApprovalTransferManagerFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - return [2]; + uint8[] memory res = new uint8[](1); + res[0] = 2; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol b/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol index 80ae0bd05..573c79ba1 100644 --- a/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol @@ -45,13 +45,15 @@ contract PercentageTransferManagerFactory is ModuleFactory { * @return uint8 */ function getTypes() external view returns(uint8[]) { - return [2]; + uint8[] memory res = new uint8[](1); + res[0] = 2; + return res; } /** * @notice Get the name of the Module */ - function getName() external view returns(bytes32) { + function getName() public view returns(bytes32) { return name; } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 655625b71..2622d7fb5 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -335,19 +335,18 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr require(modulesToData[_module].module != address(0), "Module missing"); emit ModuleRemoved(modulesToData[_module].moduleTypes, _module, now); // Remove from module type list - uint8[] moduleTypes = modulesToData[_module].moduleTypes; + uint8[] memory moduleTypes = modulesToData[_module].moduleTypes; for (uint256 i = 0; i < moduleTypes.length; i++) { _removeModuleWithIndex(moduleTypes[i], modulesToData[_module].moduleIndexes[i]); } - // Remove from module names list uint256 index = modulesToData[_module].nameIndex; bytes32 name = modulesToData[_module].name; - length = names[name].length; + uint256 length = names[name].length; names[name][index] = names[name][length - 1]; names[name].length = length - 1; if ((length - 1) != index) { - modulesToData[modules[moduleType][index]].nameIndex = index; + modulesToData[names[name][index]].nameIndex = index; } // Remove from modulesToData delete modulesToData[_module]; @@ -367,7 +366,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr modulesToData[_module].module, modulesToData[_module].moduleFactory, modulesToData[_module].isArchived, - modulesToData[_module].moduleTypes, + modulesToData[_module].moduleTypes); } /** From 4838de702475b10666134183f625780aa7a3892b Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Tue, 2 Oct 2018 22:05:04 +0100 Subject: [PATCH 010/142] Merge branch 'development-1.5.0' into support_multiple_module_types # Conflicts: # contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol # contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol # contracts/tokens/SecurityToken.sol --- CHANGELOG.md | 1 + CLI/commands/ST20Generator.js | 6 +- CLI/commands/TickerRollForward.js | 4 +- CLI/commands/common/common_functions.js | 5 + CLI/commands/contract_manager.js | 15 +- CLI/commands/dividends_manager.js | 26 +- CLI/commands/helpers/contract_addresses.js | 2 +- contracts/SecurityTokenRegistry.sol | 293 ++++++----- contracts/interfaces/IOwnable.sol | 2 +- .../interfaces/ISecurityTokenRegistry.sol | 30 ++ .../modules/Checkpoint/DividendCheckpoint.sol | 453 +++++++++--------- .../Checkpoint/ERC20DividendCheckpoint.sol | 363 ++++++++------ .../Checkpoint/EtherDividendCheckpoint.sol | 330 +++++++------ contracts/modules/Checkpoint/ICheckpoint.sol | 16 +- contracts/oracles/MakerDAOOracle.sol | 12 +- contracts/oracles/PolyOracle.sol | 22 +- contracts/tokens/SecurityToken.sol | 50 +- scripts/test.sh | 6 +- test/a_poly_oracle.js | 20 +- test/b_capped_sto.js | 18 +- test/c_checkpoints.js | 2 +- test/d_count_transfer_manager.js | 2 +- test/e_erc20_dividends.js | 48 +- test/f_ether_dividends.js | 42 +- test/g_general_permission_manager.js | 2 +- test/h_general_transfer_manager.js | 2 +- test/j_manual_approval_transfer_manager.js | 2 +- test/k_module_registry.js | 4 +- test/l_percentage_transfer_manager.js | 2 +- test/m_presale_sto.js | 12 +- test/n_security_token_registry.js | 95 +++- test/o_security_token.js | 8 +- test/r_concurrent_STO.js | 2 +- test/t_security_token_registry_proxy.js | 2 +- test/v_tracked_redemptions.js | 2 +- 35 files changed, 1086 insertions(+), 815 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52e0d50da..ca2181f6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. [__1.5.0__](https://www.npmjs.com/package/polymath-core?activeTab=readme) __15-08-18__ ## Added +* Added `name` field to dividends struct in DividendCheckpoint. #295 * Added `getTagsByType`, `getTagsByTypeAndToken`, `getModulesByType`, `getModulesByTypeAndToken` to MR * Added `getTokensByOwner` to STR * Added withholding tax to ether & erc20 dividends diff --git a/CLI/commands/ST20Generator.js b/CLI/commands/ST20Generator.js index ae8466ad0..1b7fd034b 100644 --- a/CLI/commands/ST20Generator.js +++ b/CLI/commands/ST20Generator.js @@ -23,8 +23,6 @@ const MODULES_TYPES = { DIVIDENDS: 4 } -const REG_FEE_KEY = 'tickerRegFee'; -const LAUNCH_FEE_KEY = 'stLaunchFee'; const cappedSTOFee = 20000; const usdTieredSTOFee = 100000; const tokenDetails = ""; @@ -103,8 +101,8 @@ async function step_ticker_reg(){ console.log('\n\x1b[34m%s\x1b[0m',"Token Creation - Symbol Registration"); let available = false; + let regFee = web3.utils.fromWei(await securityTokenRegistry.methods.getTickerRegistrationFee().call()); let isDeployed; - let regFee = web3.utils.fromWei(await securityTokenRegistry.methods.getUintValues(web3.utils.soliditySha3(REG_FEE_KEY)).call()); while (!available) { console.log(chalk.green(`\nRegistering the new token symbol requires ${regFee} POLY & deducted from '${Issuer.address}', Current balance is ${(await currentBalance(Issuer.address))} POLY\n`)); @@ -156,7 +154,7 @@ async function step_token_deploy(){ } else { console.log('\n\x1b[34m%s\x1b[0m',"Token Creation - Token Deployment"); - let launchFee = web3.utils.fromWei(await securityTokenRegistry.methods.getUintValues(web3.utils.soliditySha3(LAUNCH_FEE_KEY)).call()); + let launchFee = web3.utils.fromWei(await securityTokenRegistry.methods.getSecurityTokenLaunchFee().call()); console.log(chalk.green(`\nToken deployment requires ${launchFee} POLY & deducted from '${Issuer.address}', Current balance is ${(await currentBalance(Issuer.address))} POLY\n`)); if (typeof _tokenConfig !== 'undefined' && _tokenConfig.hasOwnProperty('name')) { diff --git a/CLI/commands/TickerRollForward.js b/CLI/commands/TickerRollForward.js index 732eb1b97..97bd1f519 100644 --- a/CLI/commands/TickerRollForward.js +++ b/CLI/commands/TickerRollForward.js @@ -13,8 +13,6 @@ var abis = require('./helpers/contract_abis'); let remoteNetwork = process.argv.slice(2)[0]; //batch size ///////////////////////// GLOBAL VARS ///////////////////////// -const REG_FEE_KEY = 'tickerRegFee'; - let ticker_data = []; let registered_tickers = []; let failed_tickers = []; @@ -80,7 +78,7 @@ async function readFile() { async function registerTickers() { // Poly approval for registration fees let polyBalance = BigNumber(await polyToken.methods.balanceOf(Issuer.address).call()); - let fee = web3.utils.fromWei(await securityTokenRegistry.methods.getUintValues(web3.utils.soliditySha3(REG_FEE_KEY)).call()); + let fee = web3.utils.fromWei(await securityTokenRegistry.methods.getTickerRegistrationFee().call()); let totalFee = BigNumber(ticker_data.length).mul(fee); if (totalFee.gt(polyBalance)) { diff --git a/CLI/commands/common/common_functions.js b/CLI/commands/common/common_functions.js index 07de69fec..dbf3aa8dd 100644 --- a/CLI/commands/common/common_functions.js +++ b/CLI/commands/common/common_functions.js @@ -50,7 +50,12 @@ module.exports = { sendTransaction: async function (from, action, gasPrice, value, factor) { if (typeof factor === 'undefined') factor = 1.2; + let block = await web3.eth.getBlock("latest"); + let networkGasLimit = block.gasLimit; + let gas = Math.round(factor * (await action.estimateGas({ from: from.address, value: value}))); + if (gas > networkGasLimit) gas = networkGasLimit; + console.log(chalk.black.bgYellowBright(`---- Transaction executed: ${action._method.name} - Gas limit provided: ${gas} ----`)); let nonce = await web3.eth.getTransactionCount(from.address); diff --git a/CLI/commands/contract_manager.js b/CLI/commands/contract_manager.js index 60af89396..594522f6f 100644 --- a/CLI/commands/contract_manager.js +++ b/CLI/commands/contract_manager.js @@ -13,11 +13,6 @@ var global = require('./common/global'); var contracts = require('./helpers/contract_addresses'); var abis = require('./helpers/contract_abis'); -const OWNER_KEY = 'owner'; -const REG_FEE_KEY = 'tickerRegFee'; -const LAUNCH_FEE_KEY = 'stLaunchFee'; -const EXPIRY_LIMIT_KEY = 'expiryLimit'; - // App flow let currentContract = null; @@ -79,7 +74,7 @@ async function selectContract() { async function strActions() { console.log('\n\x1b[34m%s\x1b[0m',"Security Token Registry - Main menu"); - let contractOwner = await currentContract.methods.getAddressValues(web3.utils.soliditySha3(OWNER_KEY)).call(); + let contractOwner = await currentContract.methods.owner().call(); if (contractOwner != Issuer.address) { console.log(chalk.red(`You are not the owner of this contract. Current owner is ${contractOwner}`)); @@ -117,7 +112,7 @@ async function strActions() { console.log(chalk.green(`Ticker has been updated successfuly`)); break; case 'Remove Ticker': - let tickerToRemove = readlineSync.question('Enter the token symbol that you want to add or modify: '); + let tickerToRemove = readlineSync.question('Enter the token symbol that you want to remove: '); let tickerToRemoveDetails = await currentContract.methods.getTickerDetails(tickerToRemove).call(); if (tickerToRemoveDetails[1] == 0) { console.log(chalk.yellow(`${ticker} does not exist.`)); @@ -168,7 +163,7 @@ async function strActions() { console.log(chalk.green(`Security Token has been updated successfuly`)); break; case 'Change Expiry Limit': - let currentExpiryLimit = await currentContract.methods.getUintValues(web3.utils.soliditySha3(EXPIRY_LIMIT_KEY)).call(); + let currentExpiryLimit = await currentContract.methods.getExpiryLimit().call(); console.log(chalk.yellow(`Current expiry limit is ${Math.floor(parseInt(currentExpiryLimit)/60/60/24)} days`)); let newExpiryLimit = duration.days(readlineSync.questionInt('Enter a new value in days for expiry limit: ')); let changeExpiryLimitAction = currentContract.methods.changeExpiryLimit(newExpiryLimit); @@ -177,7 +172,7 @@ async function strActions() { console.log(chalk.green(`Expiry limit was changed successfuly. New limit is ${Math.floor(parseInt(changeExpiryLimitEvent._newExpiry)/60/60/24)} days\n`)); break; case 'Change registration fee': - let currentRegFee = web3.utils.fromWei(await currentContract.methods.getUintValues(web3.utils.soliditySha3(REG_FEE_KEY)).call()); + let currentRegFee = web3.utils.fromWei(await currentContract.methods.getTickerRegistrationFee().call()); console.log(chalk.yellow(`\nCurrent ticker registration fee is ${currentRegFee} POLY`)); let newRegFee = web3.utils.toWei(readlineSync.questionInt('Enter a new value in POLY for ticker registration fee: ').toString()); let changeRegFeeAction = currentContract.methods.changeTickerRegistrationFee(newRegFee); @@ -186,7 +181,7 @@ async function strActions() { console.log(chalk.green(`Fee was changed successfuly. New fee is ${web3.utils.fromWei(changeRegFeeEvent._newFee)} POLY\n`)); break; case 'Change ST launch fee': - let currentLaunchFee = web3.utils.fromWei(await currentContract.methods.getUintValues(web3.utils.soliditySha3(LAUNCH_FEE_KEY)).call()); + let currentLaunchFee = web3.utils.fromWei(await currentContract.methods.getSecurityTokenLaunchFee().call()); console.log(chalk.yellow(`\nCurrent ST launch fee is ${currentLaunchFee} POLY`)); let newLaunchFee = web3.utils.toWei(readlineSync.questionInt('Enter a new value in POLY for ST launch fee: ').toString()); let changeLaunchFeeAction = currentContract.methods.changeSecurityLaunchFee(newLaunchFee); diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index aeb81d818..a757b78ef 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -137,10 +137,11 @@ async function start_explorer(){ await taxHoldingMenu(); break; case 'Create dividends': - let dividend = readlineSync.question(`How much ${dividendsType} would you like to distribute to token holders?: `); + let divName = readlineSync.question(`Enter a name or title to indetify this dividend: `); + let dividend = readlineSync.question(`How much ${dividendsType} would you like to distribute to token holders?: `); await checkBalance(dividend); let checkpointId = currentCheckpoint == 0 ? 0 : await selectCheckpoint(true); // If there are no checkpoints, it must create a new one - await createDividends(dividend, checkpointId); + await createDividends(divName, dividend, checkpointId); break; case 'Explore account at checkpoint': let _address = readlineSync.question('Enter address to explore: '); @@ -316,7 +317,7 @@ async function taxHoldingMenu() { } } -async function createDividends(dividend, checkpointId) { +async function createDividends(name, dividend, checkpointId) { await addDividendsModule(); let time = Math.floor(Date.now()/1000); @@ -332,17 +333,17 @@ async function createDividends(dividend, checkpointId) { await common.sendTransaction(Issuer, approveAction, defaultGasPrice); if (checkpointId > 0) { if (useDefaultExcluded) { - createDividendAction = currentDividendsModule.methods.createDividendWithCheckpoint(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend), checkpointId); + createDividendAction = currentDividendsModule.methods.createDividendWithCheckpoint(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend), checkpointId, web3.utils.toHex(name)); } else { let excluded = getExcludedFromDataFile(); - createDividendAction = currentDividendsModule.methods.createDividendWithCheckpointAndExclusions(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend), checkpointId, excluded); + createDividendAction = currentDividendsModule.methods.createDividendWithCheckpointAndExclusions(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend), checkpointId, excluded, web3.utils.toHex(name)); } } else { if (useDefaultExcluded) { - createDividendAction = currentDividendsModule.methods.createDividend(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend)); + createDividendAction = currentDividendsModule.methods.createDividend(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend), web3.utils.toHex(name)); } else { let excluded = getExcludedFromDataFile(); - createDividendAction = currentDividendsModule.methods.createDividendWithExclusions(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend), excluded); + createDividendAction = currentDividendsModule.methods.createDividendWithExclusions(maturityTime, expiryTime, polyToken._address, web3.utils.toWei(dividend), excluded, web3.utils.toHex(name)); } } let receipt = await common.sendTransaction(Issuer, createDividendAction, defaultGasPrice); @@ -351,17 +352,17 @@ async function createDividends(dividend, checkpointId) { } else if (dividendsType == 'ETH') { if (checkpointId > 0) { if (useDefaultExcluded) { - createDividendAction = currentDividendsModule.methods.createDividendWithCheckpoint(maturityTime, expiryTime, checkpointId); + createDividendAction = currentDividendsModule.methods.createDividendWithCheckpoint(maturityTime, expiryTime, checkpointId, web3.utils.toHex(name)); } else { let excluded = getExcludedFromDataFile(); - createDividendAction = currentDividendsModule.methods.createDividendWithCheckpointAndExclusions(maturityTime, expiryTime, checkpointId, excluded); + createDividendAction = currentDividendsModule.methods.createDividendWithCheckpointAndExclusions(maturityTime, expiryTime, checkpointId, excluded, web3.utils.toHex(name)); } } else { if (useDefaultExcluded) { - createDividendAction = currentDividendsModule.methods.createDividend(maturityTime, expiryTime); + createDividendAction = currentDividendsModule.methods.createDividend(maturityTime, expiryTime, web3.utils.toHex(name)); } else { let excluded = getExcludedFromDataFile(); - createDividendAction = currentDividendsModule.methods.createDividendWithExclusions(maturityTime, expiryTime, excluded); + createDividendAction = currentDividendsModule.methods.createDividendWithExclusions(maturityTime, expiryTime, excluded, web3.utils.toHex(name)); } } let receipt = await common.sendTransaction(Issuer, createDividendAction, defaultGasPrice, web3.utils.toWei(dividend)); @@ -543,7 +544,8 @@ async function selectDividend(filter) { if (dividends.length > 0) { let options = dividends.map(function(d) { - return `Created: ${moment.unix(d.created).format('MMMM Do YYYY, HH:mm:ss')} + return `${web3.utils.toAscii(d.name)} + Created: ${moment.unix(d.created).format('MMMM Do YYYY, HH:mm:ss')} Maturity: ${moment.unix(d.maturity).format('MMMM Do YYYY, HH:mm:ss')} Expiry: ${moment.unix(d.expiry).format('MMMM Do YYYY, HH:mm:ss')} At checkpoint: ${d.checkpointId} diff --git a/CLI/commands/helpers/contract_addresses.js b/CLI/commands/helpers/contract_addresses.js index 60c2531ea..b6dca4eeb 100644 --- a/CLI/commands/helpers/contract_addresses.js +++ b/CLI/commands/helpers/contract_addresses.js @@ -79,7 +79,7 @@ module.exports = { }, getModuleFactoryAddressByName: async function(stAddress, moduleType, moduleName) { let moduleRegistry = await getModuleRegistry(); - let availableModules = await moduleRegistry.methods.getAvailableModulesOfType(moduleType, stAddress).call(); + let availableModules = await moduleRegistry.methods.getModulesByTypeAndToken(moduleType, stAddress).call(); let result = null; let counter = 0; diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index 1ae6193ff..438e2eef5 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -78,8 +78,6 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // Emit when ownership of the ticker gets changed event ChangeTickerOwnership(string _ticker, address indexed _oldOwner, address indexed _newOwner); - // Emit when a ticker details is modified - event ModifyTickerDetails(address _owner, string _ticker, string _name, uint256 _registrationDate, uint256 _expiryDate, bool _status); // Emit at the time of launching a new security token event NewSecurityToken( string _ticker, @@ -88,7 +86,8 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { address indexed _owner, uint256 _addedAt, address _registrant, - bool _fromAdmin + bool _fromAdmin, + uint256 _registrationFee ); // Emit after ticker registration event RegisterTicker( @@ -97,7 +96,8 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { string _name, uint256 indexed _registrationDate, uint256 indexed _expiryDate, - bool _fromAdmin + bool _fromAdmin, + uint256 _registrationFee ); ///////////////////////////// @@ -108,7 +108,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { - require(msg.sender == getAddress(Encoder.getKey("owner"))); + require(msg.sender == owner()); _; } @@ -116,10 +116,10 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPausedOrOwner() { - if (msg.sender == getAddress(Encoder.getKey("owner"))) - _; + if (msg.sender == owner()) + _; else { - require(!getBool(Encoder.getKey("paused")), "Already paused"); + require(!isPaused(), "Already paused"); _; } } @@ -128,7 +128,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Modifier to make a function callable only when the contract is not paused and ignore is msg.sender is owner. */ modifier whenNotPaused() { - require(!getBool(Encoder.getKey("paused")), "Already paused"); + require(!isPaused(), "Already paused"); _; } @@ -137,20 +137,15 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { - require(getBool(Encoder.getKey("paused")), "Should not be paused"); + require(isPaused(), "Should not be paused"); _; } + ///////////////////////////// // Initialization ///////////////////////////// - // Constructor - constructor () public - { - - } - /** * @notice initializes instance of STR * @param _polymathRegistry is the address of the Polymath Registry @@ -162,9 +157,8 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function initialize(address _polymathRegistry, address _STFactory, uint256 _stLaunchFee, uint256 _tickerRegFee, address _polyToken, address _owner) payable external { require(!getBool(Encoder.getKey("initialised"))); - require(_STFactory != address(0) && _polyToken != address(0) && _owner != address(0) && _polymathRegistry != address(0), "In-valid address"); + require(_STFactory != address(0) && _polyToken != address(0) && _owner != address(0) && _polymathRegistry != address(0), "Invalid address"); require(_stLaunchFee != 0 && _tickerRegFee != 0, "Fees should not be 0"); - // address polyToken = _polyToken; set(Encoder.getKey("polyToken"), _polyToken); set(Encoder.getKey("stLaunchFee"), _stLaunchFee); set(Encoder.getKey("tickerRegFee"), _tickerRegFee); @@ -192,16 +186,26 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { require(_owner != address(0), "Owner should not be 0x"); require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Ticker length range (0,10]"); // Attempt to charge the reg fee if it is > 0 POLY - if (getUint(Encoder.getKey("tickerRegFee")) > 0) - require(IERC20(getAddress(Encoder.getKey("polyToken"))).transferFrom(msg.sender, address(this), getUint(Encoder.getKey("tickerRegFee"))), "Sufficent allowance is not provided"); + uint256 tickerFee = getTickerRegistrationFee(); + if (tickerFee > 0) + require(IERC20(getAddress(Encoder.getKey("polyToken"))).transferFrom(msg.sender, address(this), tickerFee), "Insufficent allowance"); string memory ticker = Util.upper(_ticker); - require(_tickerAvailable(ticker), "Ticker is already reserved"); + require(_tickerAvailable(ticker), "Ticker is reserved"); // Check whether ticker was previously registered (and expired) - address previousOwner = getAddress(Encoder.getKey("registeredTickers_owner", _ticker)); + address previousOwner = _tickerOwner(ticker); if (previousOwner != address(0)) { - _deleteTickerOwnership(previousOwner, _ticker); + _deleteTickerOwnership(previousOwner, ticker); } - _addTicker(_owner, ticker, _tokenName, now, now.add(getUint(Encoder.getKey("expiryLimit"))), false, false); + _addTicker(_owner, ticker, _tokenName, now, now.add(getExpiryLimit()), false, false, tickerFee); + } + + /** + * @notice Internal - Sets the details of the ticker + */ + function _addTicker(address _owner, string _ticker, string _tokenName, uint256 _registrationDate, uint256 _expiryDate, bool _status, bool _fromAdmin, uint256 _fee) internal { + _setTickerOwnership(_owner, _ticker); + _storeTickerDetails(_ticker, _owner, _registrationDate, _expiryDate, _tokenName, _status); + emit RegisterTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _fromAdmin, _fee); } /** @@ -218,7 +222,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Ticker length range (0,10]"); require(_expiryDate != 0 && _registrationDate != 0, "Dates should not be 0"); require(_registrationDate <= _expiryDate, "Registration date should < expiry date"); - require(_owner != address(0), "In-valid address"); + require(_owner != address(0), "Invalid address"); string memory ticker = Util.upper(_ticker); _modifyTicker(_owner, ticker, _tokenName, _registrationDate, _expiryDate, _status); } @@ -227,20 +231,22 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Internal -- Modifies the ticker details. */ function _modifyTicker(address _owner, string _ticker, string _tokenName, uint256 _registrationDate, uint256 _expiryDate, bool _status) internal { - address currentOwner = getAddress(Encoder.getKey("registeredTickers_owner", _ticker)); - if (currentOwner == address(0) && _registrationDate == 0 && _expiryDate == 0) { - _addTicker(_owner, _ticker, _tokenName, now, now.add(getUint(Encoder.getKey("expiryLimit"))), _status, true); - return; - } - // If ticker exists, and is registered to a different owner, switch over - if ((currentOwner != address(0)) && (currentOwner != _owner)) { - _transferTickerOwnership(currentOwner, _owner, _ticker); + address currentOwner = _tickerOwner(_ticker); + if (currentOwner != address(0)) { + _deleteTickerOwnership(currentOwner, _ticker); } - if (getBool(Encoder.getKey("registeredTickers_status", _ticker)) && !_status) { + if (_tickerStatus(_ticker) && !_status) { set(Encoder.getKey("tickerToSecurityToken", _ticker), address(0)); } - _storeTickerDetails(_ticker, _owner, _registrationDate, _expiryDate, _tokenName, _status); - emit RegisterTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, true); + // If status is true, there must be a security token linked to the ticker already + if (_status) { + require(getAddress(Encoder.getKey("tickerToSecurityToken", _ticker)) != address(0), "Token not registered"); + } + _addTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _status, true, uint256(0)); + } + + function _tickerOwner(string _ticker) internal view returns(address) { + return getAddress(Encoder.getKey("registeredTickers_owner", _ticker)); } /** @@ -249,12 +255,12 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function removeTicker(string _ticker) external onlyOwner { string memory ticker = Util.upper(_ticker); - address owner = getAddress(Encoder.getKey("registeredTickers_owner", ticker)); + address owner = _tickerOwner(ticker); require(owner != address(0), "Ticker doesn't exist"); _deleteTickerOwnership(owner, ticker); set(Encoder.getKey("tickerToSecurityToken", ticker), address(0)); _storeTickerDetails(ticker, address(0), 0, 0, "", false); - emit TickerRemoved(_ticker, now, msg.sender); + emit TickerRemoved(ticker, now, msg.sender); } /** @@ -263,8 +269,8 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @return bool */ function _tickerAvailable(string _ticker) internal view returns(bool) { - if (getAddress(Encoder.getKey("registeredTickers_owner", _ticker)) != address(0)) { - if (now > getUint(Encoder.getKey("registeredTickers_expiryDate", _ticker)) && !getBool(Encoder.getKey("registeredTickers_status", _ticker))) { + if (_tickerOwner(_ticker) != address(0)) { + if ((now > getUint(Encoder.getKey("registeredTickers_expiryDate", _ticker))) && !_tickerStatus(_ticker)) { return true; } else return false; @@ -272,13 +278,8 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { return true; } - /** - * @notice Internal - Sets the details of the ticker - */ - function _addTicker(address _owner, string _ticker, string _tokenName, uint256 _registrationDate, uint256 _expiryDate, bool _status, bool _fromAdmin) internal { - _setTickerOwner(_owner, _ticker); - _storeTickerDetails(_ticker, _owner, _registrationDate, _expiryDate, _tokenName, _status); - emit RegisterTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _fromAdmin); + function _tickerStatus(string _ticker) internal returns(bool) { + return getBool(Encoder.getKey("registeredTickers_status", _ticker)); } /** @@ -286,13 +287,15 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _owner is the address of the owner of the ticker * @param _ticker is the ticker symbol */ - function _setTickerOwner(address _owner, string _ticker) internal { - uint256 length = uint256(getArrayBytes32(Encoder.getKey("userToTickers", _owner)).length); - pushArray(Encoder.getKey("userToTickers", _owner), Util.stringToBytes32(_ticker)); + function _setTickerOwnership(address _owner, string _ticker) internal { + bytes32 _ownerKey = Encoder.getKey("userToTickers", _owner); + uint256 length = uint256(getArrayBytes32(_ownerKey).length); + pushArray(_ownerKey, Util.stringToBytes32(_ticker)); set(Encoder.getKey("tickerIndex", _ticker), length); - if (!getBool(Encoder.getKey("seenUsers", _owner))) { + bytes32 seenKey = Encoder.getKey("seenUsers", _owner); + if (!getBool(seenKey)) { pushArray(Encoder.getKey("activeUsers"), _owner); - set(Encoder.getKey("seenUsers", _owner), true); + set(seenKey, true); } } @@ -300,16 +303,21 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Internal - Stores the ticker details */ function _storeTickerDetails(string _ticker, address _owner, uint256 _registrationDate, uint256 _expiryDate, string _tokenName, bool _status) internal { - if (getAddress(Encoder.getKey("registeredTickers_owner", _ticker)) != _owner) - set(Encoder.getKey("registeredTickers_owner", _ticker), _owner); - if (getUint(Encoder.getKey("registeredTickers_registrationDate", _ticker)) != _registrationDate) - set(Encoder.getKey("registeredTickers_registrationDate", _ticker), _registrationDate); - if (getUint(Encoder.getKey("registeredTickers_expiryDate", _ticker)) != _expiryDate) - set(Encoder.getKey("registeredTickers_expiryDate", _ticker), _expiryDate); - if (Encoder.getKey(getString(Encoder.getKey("registeredTickers_tokenName", _ticker))) != Encoder.getKey(_tokenName)) - set(Encoder.getKey("registeredTickers_tokenName", _ticker), _tokenName); - if (getBool(Encoder.getKey("registeredTickers_status", _ticker)) != _status) - set(Encoder.getKey("registeredTickers_status", _ticker), _status); + bytes32 key = Encoder.getKey("registeredTickers_owner", _ticker); + if (getAddress(key) != _owner) + set(key, _owner); + key = Encoder.getKey("registeredTickers_registrationDate", _ticker); + if (getUint(key) != _registrationDate) + set(key, _registrationDate); + key = Encoder.getKey("registeredTickers_expiryDate", _ticker); + if (getUint(key) != _expiryDate) + set(key, _expiryDate); + key = Encoder.getKey("registeredTickers_tokenName", _ticker); + if (Encoder.getKey(getString(key)) != Encoder.getKey(_tokenName)) + set(key, _tokenName); + key = Encoder.getKey("registeredTickers_status", _ticker); + if (getBool(key) != _status) + set(key, _status); } /** @@ -319,39 +327,30 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function transferTickerOwnership(address _newOwner, string _ticker) external whenNotPausedOrOwner { string memory ticker = Util.upper(_ticker); - require(_newOwner != address(0), "In-valid address"); - require(getAddress(Encoder.getKey("registeredTickers_owner", ticker)) == msg.sender, "Not authorised"); - _transferTickerOwnership(msg.sender, _newOwner, ticker); - set(Encoder.getKey("registeredTickers_owner", ticker), _newOwner); - } - - /** - * @notice Internal - Transfers the control of ticker to a newOwner - * @param _oldOwner is the previous owner - * @param _newOwner is the the new owner - * @param _ticker is the ticker symbol - */ - function _transferTickerOwnership(address _oldOwner, address _newOwner, string _ticker) internal { - if(getBool(Encoder.getKey("registeredTickers_status", _ticker))) - require(IOwnable(getAddress(Encoder.getKey("tickerToSecurityToken", _ticker))).owner() == _newOwner, "Ticker can only be transferred to its token owner"); - - _deleteTickerOwnership(_oldOwner, _ticker); - _setTickerOwner(_newOwner, _ticker); - emit ChangeTickerOwnership(_ticker, _oldOwner, _newOwner); + require(_newOwner != address(0), "Invalid address"); + bytes32 ownerKey = Encoder.getKey("registeredTickers_owner", ticker); + require(getAddress(ownerKey) == msg.sender, "Not authorised"); + if (_tickerStatus(ticker)) + require(IOwnable(getAddress(Encoder.getKey("tickerToSecurityToken", ticker))).owner() == _newOwner, "New owner does not match token owner"); + _deleteTickerOwnership(msg.sender, ticker); + _setTickerOwnership(_newOwner, ticker); + set(ownerKey, _newOwner); + emit ChangeTickerOwnership(ticker, msg.sender, _newOwner); } /** * @notice Internal - Removes the owner of a ticker */ function _deleteTickerOwnership(address _owner, string _ticker) internal { - uint256 _index = uint256(getUint(Encoder.getKey("tickerIndex", _ticker))); - assert(_index < getArrayBytes32(Encoder.getKey("userToTickers", _owner)).length); - // deleting the _index from the data strucutre userToTickers[_oldowner][_index]; - deleteArrayBytes32(Encoder.getKey("userToTickers", _owner), _index); - - if (getArrayBytes32(Encoder.getKey("userToTickers", _owner)).length > _index) { - bytes32 switchedTicker = getArrayBytes32(Encoder.getKey("userToTickers", _owner))[_index]; - set(Encoder.getKey("tickerIndex", Util.bytes32ToString(switchedTicker)), _index); + uint256 index = uint256(getUint(Encoder.getKey("tickerIndex", _ticker))); + bytes32 ownerKey = Encoder.getKey("userToTickers", _owner); + bytes32[] memory tickers = getArrayBytes32(ownerKey); + assert(index < tickers.length); + assert(_tickerOwner(_ticker) == _owner); + deleteArrayBytes32(ownerKey, index); + if (getArrayBytes32(ownerKey).length > index) { + bytes32 switchedTicker = getArrayBytes32(ownerKey)[index]; + set(Encoder.getKey("tickerIndex", Util.bytes32ToString(switchedTicker)), index); } } @@ -361,8 +360,9 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function changeExpiryLimit(uint256 _newExpiry) external onlyOwner { require(_newExpiry >= 1 days, "Expiry should >= 1 day"); - emit ChangeExpiryLimit(getUint(Encoder.getKey('expiryLimit')), _newExpiry); - set(Encoder.getKey('expiryLimit'), _newExpiry); + bytes32 key = Encoder.getKey('expiryLimit'); + emit ChangeExpiryLimit(getUint(key), _newExpiry); + set(key, _newExpiry); } /** @@ -372,12 +372,12 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { function getTickersByOwner(address _owner) external view returns(bytes32[]) { uint counter = 0; // accessing the data structure userTotickers[_owner].length - uint _len = getArrayBytes32(Encoder.getKey("userToTickers", _owner)).length; - bytes32[] memory tempList = new bytes32[](_len); - for (uint i = 0; i < _len; i++) { - string memory _ticker = Util.bytes32ToString(getArrayBytes32(Encoder.getKey("userToTickers", _owner))[i]); - if (getUint(Encoder.getKey("registeredTickers_expiryDate", _ticker)) >= now || getBool(Encoder.getKey("registeredTickers_status", _ticker))) { - tempList[counter] = getArrayBytes32(Encoder.getKey("userToTickers", _owner))[i]; + bytes32[] memory tickers = getArrayBytes32(Encoder.getKey("userToTickers", _owner)); + bytes32[] memory tempList = new bytes32[](tickers.length); + for (uint i = 0; i < tickers.length; i++) { + string memory ticker = Util.bytes32ToString(tickers[i]); + if (getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || _tickerStatus(ticker)) { + tempList[counter] = tickers[i]; counter ++; } } @@ -437,14 +437,16 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function getTickerDetails(string _ticker) external view returns (address, uint256, uint256, string, bool) { string memory ticker = Util.upper(_ticker); - if (getBool(Encoder.getKey("registeredTickers_status", ticker)) == true || getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)) > now) { + bool tickerStatus = _tickerStatus(ticker); + uint256 expiryDate = getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)); + if ((tickerStatus == true) || (expiryDate > now)) { return ( - getAddress(Encoder.getKey("registeredTickers_owner", ticker)), + _tickerOwner(ticker), getUint(Encoder.getKey("registeredTickers_registrationDate", ticker)), - getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)), + expiryDate, getString(Encoder.getKey("registeredTickers_tokenName", ticker)), - getBool(Encoder.getKey("registeredTickers_status", ticker)) + tickerStatus ); } else return (address(0), uint256(0), uint256(0), "", false); @@ -464,15 +466,15 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { function generateSecurityToken(string _name, string _ticker, string _tokenDetails, bool _divisible) external whenNotPausedOrOwner { require(bytes(_name).length > 0 && bytes(_ticker).length > 0, "Ticker length > 0"); string memory ticker = Util.upper(_ticker); - - require(getBool(Encoder.getKey("registeredTickers_status", ticker)) != true, "Already deployed"); - require(getAddress(Encoder.getKey("registeredTickers_owner", ticker)) == msg.sender, "Not authorised"); + bytes32 statusKey = Encoder.getKey("registeredTickers_status", ticker); + require(!getBool(statusKey), "Already deployed"); + set(statusKey, true); + require(_tickerOwner(ticker) == msg.sender, "Not authorised"); require(getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now, "Ticker gets expired"); - set(Encoder.getKey("registeredTickers_status", ticker), true); - - if (getUint(Encoder.getKey("stLaunchFee")) > 0) - require(IERC20(getAddress(Encoder.getKey("polyToken"))).transferFrom(msg.sender, address(this), getUint(Encoder.getKey("stLaunchFee"))), "Insufficient allowance"); + uint256 launchFee = getSecurityTokenLaunchFee(); + if (launchFee > 0) + require(IERC20(getAddress(Encoder.getKey("polyToken"))).transferFrom(msg.sender, address(this), launchFee), "Insufficient allowance"); address newSecurityTokenAddress = ISTFactory(getSTFactoryAddress()).deployToken( _name, @@ -486,7 +488,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { _storeSecurityTokenData(newSecurityTokenAddress, ticker, _tokenDetails, now); set(Encoder.getKey("tickerToSecurityToken", ticker), newSecurityTokenAddress); - emit NewSecurityToken(ticker, _name, newSecurityTokenAddress, msg.sender, now, msg.sender, false); + emit NewSecurityToken(ticker, _name, newSecurityTokenAddress, msg.sender, now, msg.sender, false, launchFee); } /** @@ -504,11 +506,16 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { require(_deployedAt != 0 && _owner != address(0), "0 value params not allowed"); string memory ticker = Util.upper(_ticker); require(_securityToken != address(0), "ST address is 0x"); - // If ticker didn't previously exist, it will be created - _modifyTicker(_owner, ticker, _name, getUint(Encoder.getKey("registeredTickers_registrationDate", ticker)), getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)), true); + uint256 registrationTime = getUint(Encoder.getKey("registeredTickers_registrationDate", ticker)); + uint256 expiryTime = getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)); + if (registrationTime == 0) { + registrationTime = now; + expiryTime = registrationTime.add(getExpiryLimit()); + } set(Encoder.getKey("tickerToSecurityToken", ticker), _securityToken); + _modifyTicker(_owner, ticker, _name, registrationTime, expiryTime, true); _storeSecurityTokenData(_securityToken, ticker, _tokenDetails, _deployedAt); - emit NewSecurityToken(ticker, _name, _securityToken, _owner, _deployedAt, msg.sender, true); + emit NewSecurityToken(ticker, _name, _securityToken, _owner, _deployedAt, msg.sender, true, getSecurityTokenLaunchFee()); } /** @@ -566,8 +573,9 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function transferOwnership(address _newOwner) external onlyOwner { require(_newOwner != address(0)); - emit OwnershipTransferred(getAddress(Encoder.getKey("owner")), _newOwner); - set(Encoder.getKey("owner"), _newOwner); + bytes32 key = Encoder.getKey("owner"); + emit OwnershipTransferred(getAddress(key), _newOwner); + set(key, _newOwner); } /** @@ -591,9 +599,11 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _tickerRegFee is the registration fee in POLY tokens (base 18 decimals) */ function changeTickerRegistrationFee(uint256 _tickerRegFee) external onlyOwner { - require(getUint(Encoder.getKey('tickerRegFee')) != _tickerRegFee); - emit ChangeTickerRegistrationFee(getUint(Encoder.getKey('tickerRegFee')), _tickerRegFee); - set(Encoder.getKey('tickerRegFee'), _tickerRegFee); + bytes32 key = Encoder.getKey('tickerRegFee'); + uint256 fee = getUint(key); + require(fee != _tickerRegFee); + emit ChangeTickerRegistrationFee(fee, _tickerRegFee); + set(key, _tickerRegFee); } /** @@ -601,9 +611,11 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _stLaunchFee is the registration fee in POLY tokens (base 18 decimals) */ function changeSecurityLaunchFee(uint256 _stLaunchFee) external onlyOwner { - require(getUint(Encoder.getKey("stLaunchFee")) != _stLaunchFee); - emit ChangeSecurityLaunchFee(getUint(Encoder.getKey("stLaunchFee")), _stLaunchFee); - set(Encoder.getKey("stLaunchFee"), _stLaunchFee); + bytes32 key = Encoder.getKey('stLaunchFee'); + uint256 fee = getUint(key); + require(fee != _stLaunchFee); + emit ChangeSecurityLaunchFee(fee, _stLaunchFee); + set(key, _stLaunchFee); } /** @@ -614,7 +626,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { require(_tokenContract != address(0)); IERC20 token = IERC20(_tokenContract); uint256 balance = token.balanceOf(address(this)); - require(token.transfer(getAddress(Encoder.getKey("owner")), balance)); + require(token.transfer(owner(), balance)); } /** @@ -667,5 +679,44 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { set(Encoder.getKey("polyToken"), _newAddress); } + /** + * @notice Gets the security token launch fee + * @return Fee amount + */ + function getSecurityTokenLaunchFee() public view returns(uint256) { + return getUint(Encoder.getKey("stLaunchFee")); + } + + /** + * @notice Gets the ticker registration fee + * @return Fee amount + */ + function getTickerRegistrationFee() public view returns(uint256) { + return getUint(Encoder.getKey("tickerRegFee")); + } + + /** + * @notice Gets the expiry limit + * @return Expiry limit + */ + function getExpiryLimit() public view returns(uint256) { + return getUint(Encoder.getKey("expiryLimit")); + } + + /** + * @notice Check whether the registry is paused or not + * @return bool + */ + function isPaused() public view returns(bool) { + return getBool(Encoder.getKey("paused")); + } + + /** + * @notice Gets the owner of the contract + * @return address owner + */ + function owner() public view returns(address) { + return getAddress(Encoder.getKey("owner")); + } } diff --git a/contracts/interfaces/IOwnable.sol b/contracts/interfaces/IOwnable.sol index 15849e181..de8a8d14f 100644 --- a/contracts/interfaces/IOwnable.sol +++ b/contracts/interfaces/IOwnable.sol @@ -10,7 +10,7 @@ interface IOwnable { /** * @dev Returns owner */ - function owner() external returns (address); + function owner() external view returns (address); /** * @dev Allows the current owner to relinquish control of the contract. diff --git a/contracts/interfaces/ISecurityTokenRegistry.sol b/contracts/interfaces/ISecurityTokenRegistry.sol index d7ec8f9f0..2bacd39d7 100644 --- a/contracts/interfaces/ISecurityTokenRegistry.sol +++ b/contracts/interfaces/ISecurityTokenRegistry.sol @@ -159,4 +159,34 @@ interface ISecurityTokenRegistry { */ function updatePolyTokenAddress(address _newAddress) external; + /** + * @notice Gets the security token launch fee + * @return Fee amount + */ + function getSecurityTokenLaunchFee() external view returns(uint256); + + /** + * @notice Gets the ticker registration fee + * @return Fee amount + */ + function getTickerRegistrationFee() external view returns(uint256); + + /** + * @notice Gets the expiry limit + * @return Expiry limit + */ + function getExpiryLimit() external view returns(uint256); + + /** + * @notice Check whether the registry is paused or not + * @return bool + */ + function isPaused() external view returns(bool); + + /** + * @notice Gets the owner of the contract + * @return address owner + */ + function owner() external view returns(address); + } diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index d751e02fe..fc70a9fde 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -1,226 +1,227 @@ -pragma solidity ^0.4.24; - -import "./ICheckpoint.sol"; -import "../Module.sol"; -import "../../interfaces/ISecurityToken.sol"; -import "openzeppelin-solidity/contracts/math/SafeMath.sol"; -import "openzeppelin-solidity/contracts/math/Math.sol"; - -/** - * @title Checkpoint module for issuing ether dividends - * @dev abstract contract - */ -contract DividendCheckpoint is ICheckpoint, Module { - using SafeMath for uint256; - - uint256 public EXCLUDED_ADDRESS_LIMIT = 50; - bytes32 public constant DISTRIBUTE = "DISTRIBUTE"; - - struct Dividend { - uint256 checkpointId; - uint256 created; // Time at which the dividend was created - uint256 maturity; // Time after which dividend can be claimed - set to 0 to bypass - uint256 expiry; // Time until which dividend can be claimed - after this time any remaining amount can be withdrawn by issuer - set to very high value to bypass - uint256 amount; // Dividend amount in WEI - uint256 claimedAmount; // Amount of dividend claimed so far - uint256 totalSupply; // Total supply at the associated checkpoint (avoids recalculating this) - bool reclaimed; // True if expiry has passed and issuer has reclaimed remaining dividend - uint256 dividendWithheld; - uint256 dividendWithheldReclaimed; - mapping (address => bool) claimed; // List of addresses which have claimed dividend - mapping (address => bool) dividendExcluded; // List of addresses which cannot claim dividends - } - - // List of all dividends - Dividend[] public dividends; - - // List of addresses which cannot claim dividends - address[] public excluded; - - // Mapping from address to withholding tax as a percentage * 10**16 - mapping (address => uint256) public withholdingTax; - - // Total amount of ETH withheld per investor - mapping (address => uint256) public investorWithheld; - - event SetDefaultExcludedAddresses(address[] _excluded, uint256 _timestamp); - event SetWithholding(address[] _investors, uint256[] _withholding, uint256 _timestamp); - event SetWithholdingFixed(address[] _investors, uint256 _withholding, uint256 _timestamp); - - modifier validDividendIndex(uint256 _dividendIndex) { - require(_dividendIndex < dividends.length, "Incorrect dividend index"); - require(now >= dividends[_dividendIndex].maturity, "Dividend maturity is in the future"); - require(now < dividends[_dividendIndex].expiry, "Dividend expiry is in the past"); - require(!dividends[_dividendIndex].reclaimed, "Dividend has been reclaimed by issuer"); - _; - } - - /** - * @notice Init function i.e generalise function to maintain the structure of the module contract - * @return bytes4 - */ - function getInitFunction() public pure returns (bytes4) { - return bytes4(0); - } - - /** - * @notice Return the default excluded addresses - * @return List of excluded addresses - */ - function getDefaultExcluded() external view returns (address[]) { - return excluded; - } - - /** - * @notice Function to clear and set list of excluded addresses used for future dividends - * @param _excluded addresses of investor - */ - function setDefaultExcluded(address[] _excluded) public onlyOwner { - require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many excluded addresses"); - excluded = _excluded; - emit SetDefaultExcludedAddresses(excluded, now); - } - - /** - * @notice Function to set withholding tax rates for investors - * @param _investors addresses of investor - * @param _withholding withholding tax for individual investors (multiplied by 10**16) - */ - function setWithholding(address[] _investors, uint256[] _withholding) public onlyOwner { - require(_investors.length == _withholding.length, "Mismatched input lengths"); - emit SetWithholding(_investors, _withholding, now); - for (uint256 i = 0; i < _investors.length; i++) { - require(_withholding[i] <= 10**18, "Incorrect withholding tax"); - withholdingTax[_investors[i]] = _withholding[i]; - } - } - - /** - * @notice Function to set withholding tax rates for investors - * @param _investors addresses of investor - * @param _withholding withholding tax for all investors (multiplied by 10**16) - */ - function setWithholdingFixed(address[] _investors, uint256 _withholding) public onlyOwner { - require(_withholding <= 10**18, "Incorrect withholding tax"); - emit SetWithholdingFixed(_investors, _withholding, now); - for (uint256 i = 0; i < _investors.length; i++) { - withholdingTax[_investors[i]] = _withholding; - } - } - - /** - * @notice Issuer can push dividends to provided addresses - * @param _dividendIndex Dividend to push - * @param _payees Addresses to which to push the dividend - */ - function pushDividendPaymentToAddresses(uint256 _dividendIndex, address[] _payees) public withPerm(DISTRIBUTE) validDividendIndex(_dividendIndex) { - Dividend storage dividend = dividends[_dividendIndex]; - for (uint256 i = 0; i < _payees.length; i++) { - if ((!dividend.claimed[_payees[i]]) && (!dividend.dividendExcluded[_payees[i]])) { - _payDividend(_payees[i], dividend, _dividendIndex); - } - } - } - - /** - * @notice Issuer can push dividends using the investor list from the security token - * @param _dividendIndex Dividend to push - * @param _start Index in investor list at which to start pushing dividends - * @param _iterations Number of addresses to push dividends for - */ - function pushDividendPayment(uint256 _dividendIndex, uint256 _start, uint256 _iterations) public withPerm(DISTRIBUTE) validDividendIndex(_dividendIndex) { - Dividend storage dividend = dividends[_dividendIndex]; - uint256 numberInvestors = ISecurityToken(securityToken).getInvestorsLength(); - for (uint256 i = _start; i < Math.min256(numberInvestors, _start.add(_iterations)); i++) { - address payee = ISecurityToken(securityToken).investors(i); - if ((!dividend.claimed[payee]) && (!dividend.dividendExcluded[payee])) { - _payDividend(payee, dividend, _dividendIndex); - } - } - } - - /** - * @notice Investors can pull their own dividends - * @param _dividendIndex Dividend to pull - */ - function pullDividendPayment(uint256 _dividendIndex) public validDividendIndex(_dividendIndex) - { - Dividend storage dividend = dividends[_dividendIndex]; - require(!dividend.claimed[msg.sender], "Dividend already claimed by msg.sender"); - require(!dividend.dividendExcluded[msg.sender], "msg.sender excluded from Dividend"); - _payDividend(msg.sender, dividend, _dividendIndex); - } - - /** - * @notice Internal function for paying dividends - * @param _payee address of investor - * @param _dividend storage with previously issued dividends - * @param _dividendIndex Dividend to pay - */ - function _payDividend(address _payee, Dividend storage _dividend, uint256 _dividendIndex) internal; - - /** - * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends - * @param _dividendIndex Dividend to reclaim - */ - function reclaimDividend(uint256 _dividendIndex) external; - - /** - * @notice Calculate amount of dividends claimable - * @param _dividendIndex Dividend to calculate - * @param _payee Affected investor address - * @return claim, withheld amounts - */ - function calculateDividend(uint256 _dividendIndex, address _payee) public view returns(uint256, uint256) { - require(_dividendIndex < dividends.length, "Incorrect dividend index"); - Dividend storage dividend = dividends[_dividendIndex]; - if (dividend.claimed[_payee] || dividend.dividendExcluded[_payee]) { - return (0, 0); - } - uint256 balance = ISecurityToken(securityToken).balanceOfAt(_payee, dividend.checkpointId); - uint256 claim = balance.mul(dividend.amount).div(dividend.totalSupply); - uint256 withheld = claim.mul(withholdingTax[_payee]).div(uint256(10**18)); - return (claim, withheld); - } - - /** - * @notice Get the index according to the checkpoint id - * @param _checkpointId Checkpoint id to query - * @return uint256[] - */ - function getDividendIndex(uint256 _checkpointId) public view returns(uint256[]) { - uint256 counter = 0; - for(uint256 i = 0; i < dividends.length; i++) { - if (dividends[i].checkpointId == _checkpointId) { - counter++; - } - } - - uint256[] memory index = new uint256[](counter); - counter = 0; - for(uint256 j = 0; j < dividends.length; j++) { - if (dividends[j].checkpointId == _checkpointId) { - index[counter] = j; - counter++; - } - } - return index; - } - - /** - * @notice Allows issuer to withdraw withheld tax - * @param _dividendIndex Dividend to withdraw from - */ - function withdrawWithholding(uint256 _dividendIndex) external; - - /** - * @notice Return the permissions flag that are associated with STO - * @return bytes32 array - */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); - allPermissions[0] = DISTRIBUTE; - return allPermissions; - } - -} +pragma solidity ^0.4.24; + +import "./ICheckpoint.sol"; +import "../Module.sol"; +import "../../interfaces/ISecurityToken.sol"; +import "openzeppelin-solidity/contracts/math/SafeMath.sol"; +import "openzeppelin-solidity/contracts/math/Math.sol"; + +/** + * @title Checkpoint module for issuing ether dividends + * @dev abstract contract + */ +contract DividendCheckpoint is ICheckpoint, Module { + using SafeMath for uint256; + + uint256 public EXCLUDED_ADDRESS_LIMIT = 50; + bytes32 public constant DISTRIBUTE = "DISTRIBUTE"; + + struct Dividend { + uint256 checkpointId; + uint256 created; // Time at which the dividend was created + uint256 maturity; // Time after which dividend can be claimed - set to 0 to bypass + uint256 expiry; // Time until which dividend can be claimed - after this time any remaining amount can be withdrawn by issuer - set to very high value to bypass + uint256 amount; // Dividend amount in WEI + uint256 claimedAmount; // Amount of dividend claimed so far + uint256 totalSupply; // Total supply at the associated checkpoint (avoids recalculating this) + bool reclaimed; // True if expiry has passed and issuer has reclaimed remaining dividend + uint256 dividendWithheld; + uint256 dividendWithheldReclaimed; + mapping (address => bool) claimed; // List of addresses which have claimed dividend + mapping (address => bool) dividendExcluded; // List of addresses which cannot claim dividends + bytes32 name; // Name/title - used for identification + } + + // List of all dividends + Dividend[] public dividends; + + // List of addresses which cannot claim dividends + address[] public excluded; + + // Mapping from address to withholding tax as a percentage * 10**16 + mapping (address => uint256) public withholdingTax; + + // Total amount of ETH withheld per investor + mapping (address => uint256) public investorWithheld; + + event SetDefaultExcludedAddresses(address[] _excluded, uint256 _timestamp); + event SetWithholding(address[] _investors, uint256[] _withholding, uint256 _timestamp); + event SetWithholdingFixed(address[] _investors, uint256 _withholding, uint256 _timestamp); + + modifier validDividendIndex(uint256 _dividendIndex) { + require(_dividendIndex < dividends.length, "Incorrect dividend index"); + require(now >= dividends[_dividendIndex].maturity, "Dividend maturity is in the future"); + require(now < dividends[_dividendIndex].expiry, "Dividend expiry is in the past"); + require(!dividends[_dividendIndex].reclaimed, "Dividend has been reclaimed by issuer"); + _; + } + + /** + * @notice Init function i.e generalise function to maintain the structure of the module contract + * @return bytes4 + */ + function getInitFunction() public pure returns (bytes4) { + return bytes4(0); + } + + /** + * @notice Return the default excluded addresses + * @return List of excluded addresses + */ + function getDefaultExcluded() external view returns (address[]) { + return excluded; + } + + /** + * @notice Function to clear and set list of excluded addresses used for future dividends + * @param _excluded addresses of investor + */ + function setDefaultExcluded(address[] _excluded) public onlyOwner { + require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many excluded addresses"); + excluded = _excluded; + emit SetDefaultExcludedAddresses(excluded, now); + } + + /** + * @notice Function to set withholding tax rates for investors + * @param _investors addresses of investor + * @param _withholding withholding tax for individual investors (multiplied by 10**16) + */ + function setWithholding(address[] _investors, uint256[] _withholding) public onlyOwner { + require(_investors.length == _withholding.length, "Mismatched input lengths"); + emit SetWithholding(_investors, _withholding, now); + for (uint256 i = 0; i < _investors.length; i++) { + require(_withholding[i] <= 10**18, "Incorrect withholding tax"); + withholdingTax[_investors[i]] = _withholding[i]; + } + } + + /** + * @notice Function to set withholding tax rates for investors + * @param _investors addresses of investor + * @param _withholding withholding tax for all investors (multiplied by 10**16) + */ + function setWithholdingFixed(address[] _investors, uint256 _withholding) public onlyOwner { + require(_withholding <= 10**18, "Incorrect withholding tax"); + emit SetWithholdingFixed(_investors, _withholding, now); + for (uint256 i = 0; i < _investors.length; i++) { + withholdingTax[_investors[i]] = _withholding; + } + } + + /** + * @notice Issuer can push dividends to provided addresses + * @param _dividendIndex Dividend to push + * @param _payees Addresses to which to push the dividend + */ + function pushDividendPaymentToAddresses(uint256 _dividendIndex, address[] _payees) public withPerm(DISTRIBUTE) validDividendIndex(_dividendIndex) { + Dividend storage dividend = dividends[_dividendIndex]; + for (uint256 i = 0; i < _payees.length; i++) { + if ((!dividend.claimed[_payees[i]]) && (!dividend.dividendExcluded[_payees[i]])) { + _payDividend(_payees[i], dividend, _dividendIndex); + } + } + } + + /** + * @notice Issuer can push dividends using the investor list from the security token + * @param _dividendIndex Dividend to push + * @param _start Index in investor list at which to start pushing dividends + * @param _iterations Number of addresses to push dividends for + */ + function pushDividendPayment(uint256 _dividendIndex, uint256 _start, uint256 _iterations) public withPerm(DISTRIBUTE) validDividendIndex(_dividendIndex) { + Dividend storage dividend = dividends[_dividendIndex]; + uint256 numberInvestors = ISecurityToken(securityToken).getInvestorsLength(); + for (uint256 i = _start; i < Math.min256(numberInvestors, _start.add(_iterations)); i++) { + address payee = ISecurityToken(securityToken).investors(i); + if ((!dividend.claimed[payee]) && (!dividend.dividendExcluded[payee])) { + _payDividend(payee, dividend, _dividendIndex); + } + } + } + + /** + * @notice Investors can pull their own dividends + * @param _dividendIndex Dividend to pull + */ + function pullDividendPayment(uint256 _dividendIndex) public validDividendIndex(_dividendIndex) + { + Dividend storage dividend = dividends[_dividendIndex]; + require(!dividend.claimed[msg.sender], "Dividend already claimed by msg.sender"); + require(!dividend.dividendExcluded[msg.sender], "msg.sender excluded from Dividend"); + _payDividend(msg.sender, dividend, _dividendIndex); + } + + /** + * @notice Internal function for paying dividends + * @param _payee address of investor + * @param _dividend storage with previously issued dividends + * @param _dividendIndex Dividend to pay + */ + function _payDividend(address _payee, Dividend storage _dividend, uint256 _dividendIndex) internal; + + /** + * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends + * @param _dividendIndex Dividend to reclaim + */ + function reclaimDividend(uint256 _dividendIndex) external; + + /** + * @notice Calculate amount of dividends claimable + * @param _dividendIndex Dividend to calculate + * @param _payee Affected investor address + * @return claim, withheld amounts + */ + function calculateDividend(uint256 _dividendIndex, address _payee) public view returns(uint256, uint256) { + require(_dividendIndex < dividends.length, "Incorrect dividend index"); + Dividend storage dividend = dividends[_dividendIndex]; + if (dividend.claimed[_payee] || dividend.dividendExcluded[_payee]) { + return (0, 0); + } + uint256 balance = ISecurityToken(securityToken).balanceOfAt(_payee, dividend.checkpointId); + uint256 claim = balance.mul(dividend.amount).div(dividend.totalSupply); + uint256 withheld = claim.mul(withholdingTax[_payee]).div(uint256(10**18)); + return (claim, withheld); + } + + /** + * @notice Get the index according to the checkpoint id + * @param _checkpointId Checkpoint id to query + * @return uint256[] + */ + function getDividendIndex(uint256 _checkpointId) public view returns(uint256[]) { + uint256 counter = 0; + for(uint256 i = 0; i < dividends.length; i++) { + if (dividends[i].checkpointId == _checkpointId) { + counter++; + } + } + + uint256[] memory index = new uint256[](counter); + counter = 0; + for(uint256 j = 0; j < dividends.length; j++) { + if (dividends[j].checkpointId == _checkpointId) { + index[counter] = j; + counter++; + } + } + return index; + } + + /** + * @notice Allows issuer to withdraw withheld tax + * @param _dividendIndex Dividend to withdraw from + */ + function withdrawWithholding(uint256 _dividendIndex) external; + + /** + * @notice Return the permissions flag that are associated with STO + * @return bytes32 array + */ + function getPermissions() public view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](1); + allPermissions[0] = DISTRIBUTE; + return allPermissions; + } + +} diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol index ad61b24a8..60d84a41b 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol @@ -1,157 +1,206 @@ -pragma solidity ^0.4.24; - -import "./DividendCheckpoint.sol"; -import "../../interfaces/IERC20.sol"; - -/** - * @title Checkpoint module for issuing ERC20 dividends - */ -contract ERC20DividendCheckpoint is DividendCheckpoint { - using SafeMath for uint256; - - // Mapping to token address for each dividend - mapping (uint256 => address) public dividendTokens; - - event ERC20DividendDeposited(address indexed _depositor, uint256 _checkpointId, uint256 _created, uint256 _maturity, uint256 _expiry, address indexed _token, uint256 _amount, uint256 _totalSupply, uint256 _dividendIndex); - event ERC20DividendClaimed(address indexed _payee, uint256 _dividendIndex, address indexed _token, uint256 _amount, uint256 _withheld); - event ERC20DividendReclaimed(address indexed _claimer, uint256 _dividendIndex, address indexed _token, uint256 _claimedAmount); - event ERC20DividendWithholdingWithdrawn(address indexed _claimer, uint256 _dividendIndex, address indexed _token, uint256 _withheldAmount); - - /** - * @notice Constructor - * @param _securityToken Address of the security token - * @param _polyAddress Address of the polytoken - */ - constructor (address _securityToken, address _polyAddress) public - Module(_securityToken, _polyAddress) - { - } - - /** - * @notice Creates a dividend and checkpoint for the dividend - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - * @param _token Address of ERC20 token in which dividend is to be denominated - * @param _amount Amount of specified token for dividend - */ - function createDividend(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount) external onlyOwner { - createDividendWithExclusions(_maturity, _expiry, _token, _amount, excluded); - } - - /** - * @notice Creates a dividend with a provided checkpoint - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - * @param _token Address of ERC20 token in which dividend is to be denominated - * @param _amount Amount of specified token for dividend - * @param _checkpointId Checkpoint id from which to create dividends - */ - function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, uint256 _checkpointId) external onlyOwner { - createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, _checkpointId, excluded); - } - - /** - * @notice Creates a dividend and checkpoint for the dividend - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - * @param _token Address of ERC20 token in which dividend is to be denominated - * @param _amount Amount of specified token for dividend - * @param _excluded List of addresses to exclude - */ - function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, address[] _excluded) public onlyOwner { - uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); - createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, checkpointId, _excluded); - } - - /** - * @notice Creates a dividend with a provided checkpoint - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - * @param _token Address of ERC20 token in which dividend is to be denominated - * @param _amount Amount of specified token for dividend - * @param _checkpointId Checkpoint id from which to create dividends - * @param _excluded List of addresses to exclude - */ - function createDividendWithCheckpointAndExclusions(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, uint256 _checkpointId, address[] _excluded) public onlyOwner { - require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many addresses excluded"); - require(_expiry > _maturity, "Expiry is before maturity"); - require(_expiry > now, "Expiry is in the past"); - require(_amount > 0, "No dividend sent"); - require(_token != address(0), "0x not valid token"); - require(_checkpointId <= ISecurityToken(securityToken).currentCheckpointId(), "Invalid checkpoint"); - require(IERC20(_token).transferFrom(msg.sender, address(this), _amount), "Unable to transfer tokens for dividend"); - uint256 dividendIndex = dividends.length; - uint256 currentSupply = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); - uint256 excludedSupply = 0; - for (uint256 i = 0; i < _excluded.length; i++) { - excludedSupply = excludedSupply.add(ISecurityToken(securityToken).balanceOfAt(_excluded[i], _checkpointId)); - } - dividends.push( - Dividend( - _checkpointId, - now, - _maturity, - _expiry, - _amount, - 0, - currentSupply.sub(excludedSupply), - false, - 0, - 0 - ) - ); - for (uint256 j = 0; j < _excluded.length; j++) { - dividends[dividends.length - 1].dividendExcluded[_excluded[j]] = true; - } - dividendTokens[dividendIndex] = _token; - emit ERC20DividendDeposited(msg.sender, _checkpointId, now, _maturity, _expiry, _token, _amount, currentSupply, dividendIndex); - } - - /** - * @notice Internal function for paying dividends - * @param _payee address of investor - * @param _dividend storage with previously issued dividends - * @param _dividendIndex Dividend to pay - */ - function _payDividend(address _payee, Dividend storage _dividend, uint256 _dividendIndex) internal { - (uint256 claim, uint256 withheld) = calculateDividend(_dividendIndex, _payee); - _dividend.claimed[_payee] = true; - _dividend.claimedAmount = claim.add(_dividend.claimedAmount); - uint256 claimAfterWithheld = claim.sub(withheld); - if (claimAfterWithheld > 0) { - require(IERC20(dividendTokens[_dividendIndex]).transfer(_payee, claimAfterWithheld), "Unable to transfer tokens"); - _dividend.dividendWithheld = _dividend.dividendWithheld.add(withheld); - investorWithheld[_payee] = investorWithheld[_payee].add(withheld); - emit ERC20DividendClaimed(_payee, _dividendIndex, dividendTokens[_dividendIndex], claim, withheld); - } - } - - /** - * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends - * @param _dividendIndex Dividend to reclaim - */ - function reclaimDividend(uint256 _dividendIndex) external onlyOwner { - require(_dividendIndex < dividends.length, "Incorrect dividend index"); - require(now >= dividends[_dividendIndex].expiry, "Dividend expiry is in the future"); - require(!dividends[_dividendIndex].reclaimed, "Dividend already claimed"); - dividends[_dividendIndex].reclaimed = true; - Dividend storage dividend = dividends[_dividendIndex]; - uint256 remainingAmount = dividend.amount.sub(dividend.claimedAmount); - require(IERC20(dividendTokens[_dividendIndex]).transfer(msg.sender, remainingAmount), "Unable to transfer tokens"); - emit ERC20DividendReclaimed(msg.sender, _dividendIndex, dividendTokens[_dividendIndex], remainingAmount); - } - - /** - * @notice Allows issuer to withdraw withheld tax - * @param _dividendIndex Dividend to withdraw from - */ - function withdrawWithholding(uint256 _dividendIndex) external onlyOwner { - require(_dividendIndex < dividends.length, "Incorrect dividend index"); - Dividend storage dividend = dividends[_dividendIndex]; - uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); - dividend.dividendWithheldReclaimed = dividend.dividendWithheld; - require(IERC20(dividendTokens[_dividendIndex]).transfer(msg.sender, remainingWithheld), "Unable to transfer tokens"); - emit ERC20DividendWithholdingWithdrawn(msg.sender, _dividendIndex, dividendTokens[_dividendIndex], remainingWithheld); - } - -} +pragma solidity ^0.4.24; + +import "./DividendCheckpoint.sol"; +import "../../interfaces/IERC20.sol"; + +/** + * @title Checkpoint module for issuing ERC20 dividends + */ +contract ERC20DividendCheckpoint is DividendCheckpoint { + using SafeMath for uint256; + + // Mapping to token address for each dividend + mapping (uint256 => address) public dividendTokens; + + event ERC20DividendDeposited(address indexed _depositor, uint256 _checkpointId, uint256 _created, uint256 _maturity, uint256 _expiry, address indexed _token, uint256 _amount, uint256 _totalSupply, uint256 _dividendIndex, bytes32 indexed _name); + event ERC20DividendClaimed(address indexed _payee, uint256 _dividendIndex, address indexed _token, uint256 _amount, uint256 _withheld); + event ERC20DividendReclaimed(address indexed _claimer, uint256 _dividendIndex, address indexed _token, uint256 _claimedAmount); + event ERC20DividendWithholdingWithdrawn(address indexed _claimer, uint256 _dividendIndex, address indexed _token, uint256 _withheldAmount); + + /** + * @notice Constructor + * @param _securityToken Address of the security token + * @param _polyAddress Address of the polytoken + */ + constructor (address _securityToken, address _polyAddress) public + Module(_securityToken, _polyAddress) + { + } + + /** + * @notice Creates a dividend and checkpoint for the dividend + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _token Address of ERC20 token in which dividend is to be denominated + * @param _amount Amount of specified token for dividend + * @param _name name/title for identification + */ + function createDividend(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, bytes32 _name) external onlyOwner { + createDividendWithExclusions(_maturity, _expiry, _token, _amount, excluded, _name); + } + + /** + * @notice Creates a dividend with a provided checkpoint + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _token Address of ERC20 token in which dividend is to be denominated + * @param _amount Amount of specified token for dividend + * @param _checkpointId Checkpoint id from which to create dividends + * @param _name name/title for identification + */ + function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, uint256 _checkpointId, bytes32 _name) external onlyOwner { + _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, _checkpointId, excluded, _name); + } + + /** + * @notice Creates a dividend and checkpoint for the dividend + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _token Address of ERC20 token in which dividend is to be denominated + * @param _amount Amount of specified token for dividend + * @param _excluded List of addresses to exclude + * @param _name name/title for identification + */ + function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, address[] _excluded, bytes32 _name) public onlyOwner { + uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); + _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, checkpointId, _excluded, _name); + } + + /** + * @notice Creates a dividend with a provided checkpoint + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _token Address of ERC20 token in which dividend is to be denominated + * @param _amount Amount of specified token for dividend + * @param _checkpointId Checkpoint id from which to create dividends + * @param _excluded List of addresses to exclude + * @param _name name/title for identification + */ + function createDividendWithCheckpointAndExclusions( + uint256 _maturity, + uint256 _expiry, + address _token, + uint256 _amount, + uint256 _checkpointId, + address[] _excluded, + bytes32 _name + ) + public + onlyOwner + { + _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, _checkpointId, _excluded, _name); + } + + /** + * @notice Creates a dividend with a provided checkpoint + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _token Address of ERC20 token in which dividend is to be denominated + * @param _amount Amount of specified token for dividend + * @param _checkpointId Checkpoint id from which to create dividends + * @param _excluded List of addresses to exclude + * @param _name name/title for identification + */ + function _createDividendWithCheckpointAndExclusions( + uint256 _maturity, + uint256 _expiry, + address _token, + uint256 _amount, + uint256 _checkpointId, + address[] _excluded, + bytes32 _name + ) + internal + { + require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many addresses excluded"); + require(_expiry > _maturity, "Expiry is before maturity"); + require(_expiry > now, "Expiry is in the past"); + require(_amount > 0, "No dividend sent"); + require(_token != address(0), "0x not valid token"); + require(_checkpointId <= ISecurityToken(securityToken).currentCheckpointId(), "Invalid checkpoint"); + require(IERC20(_token).transferFrom(msg.sender, address(this), _amount), "Unable to transfer tokens for dividend"); + require(_name[0] != 0); + uint256 dividendIndex = dividends.length; + uint256 currentSupply = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); + uint256 excludedSupply = 0; + for (uint256 i = 0; i < _excluded.length; i++) { + excludedSupply = excludedSupply.add(ISecurityToken(securityToken).balanceOfAt(_excluded[i], _checkpointId)); + } + dividends.push( + Dividend( + _checkpointId, + now, + _maturity, + _expiry, + _amount, + 0, + currentSupply.sub(excludedSupply), + false, + 0, + 0, + _name + ) + ); + for (uint256 j = 0; j < _excluded.length; j++) { + dividends[dividends.length - 1].dividendExcluded[_excluded[j]] = true; + } + dividendTokens[dividendIndex] = _token; + _emitERC20DividendDepositedEvent(_checkpointId, _maturity, _expiry, _token, _amount, currentSupply, dividendIndex, _name); + } + + /** + * @notice emits the ERC20DividendDeposited event. + * Seperated into a different function as a workaround for stack too deep error + */ + function _emitERC20DividendDepositedEvent(uint256 _checkpointId, uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, uint256 currentSupply, uint256 dividendIndex, bytes32 _name) internal { + emit ERC20DividendDeposited(msg.sender, _checkpointId, now, _maturity, _expiry, _token, _amount, currentSupply, dividendIndex, _name); + } + + /** + * @notice Internal function for paying dividends + * @param _payee address of investor + * @param _dividend storage with previously issued dividends + * @param _dividendIndex Dividend to pay + */ + function _payDividend(address _payee, Dividend storage _dividend, uint256 _dividendIndex) internal { + (uint256 claim, uint256 withheld) = calculateDividend(_dividendIndex, _payee); + _dividend.claimed[_payee] = true; + _dividend.claimedAmount = claim.add(_dividend.claimedAmount); + uint256 claimAfterWithheld = claim.sub(withheld); + if (claimAfterWithheld > 0) { + require(IERC20(dividendTokens[_dividendIndex]).transfer(_payee, claimAfterWithheld), "Unable to transfer tokens"); + _dividend.dividendWithheld = _dividend.dividendWithheld.add(withheld); + investorWithheld[_payee] = investorWithheld[_payee].add(withheld); + emit ERC20DividendClaimed(_payee, _dividendIndex, dividendTokens[_dividendIndex], claim, withheld); + } + } + + /** + * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends + * @param _dividendIndex Dividend to reclaim + */ + function reclaimDividend(uint256 _dividendIndex) external onlyOwner { + require(_dividendIndex < dividends.length, "Incorrect dividend index"); + require(now >= dividends[_dividendIndex].expiry, "Dividend expiry is in the future"); + require(!dividends[_dividendIndex].reclaimed, "Dividend already claimed"); + dividends[_dividendIndex].reclaimed = true; + Dividend storage dividend = dividends[_dividendIndex]; + uint256 remainingAmount = dividend.amount.sub(dividend.claimedAmount); + require(IERC20(dividendTokens[_dividendIndex]).transfer(msg.sender, remainingAmount), "Unable to transfer tokens"); + emit ERC20DividendReclaimed(msg.sender, _dividendIndex, dividendTokens[_dividendIndex], remainingAmount); + } + + /** + * @notice Allows issuer to withdraw withheld tax + * @param _dividendIndex Dividend to withdraw from + */ + function withdrawWithholding(uint256 _dividendIndex) external onlyOwner { + require(_dividendIndex < dividends.length, "Incorrect dividend index"); + Dividend storage dividend = dividends[_dividendIndex]; + uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); + dividend.dividendWithheldReclaimed = dividend.dividendWithheld; + require(IERC20(dividendTokens[_dividendIndex]).transfer(msg.sender, remainingWithheld), "Unable to transfer tokens"); + emit ERC20DividendWithholdingWithdrawn(msg.sender, _dividendIndex, dividendTokens[_dividendIndex], remainingWithheld); + } + +} diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol index 1d17e1abb..d8ecb2e9a 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol @@ -1,147 +1,183 @@ -pragma solidity ^0.4.24; - -import "./DividendCheckpoint.sol"; - -/** - * @title Checkpoint module for issuing ether dividends - */ -contract EtherDividendCheckpoint is DividendCheckpoint { - using SafeMath for uint256; - - event EtherDividendDeposited(address indexed _depositor, uint256 _checkpointId, uint256 _created, uint256 _maturity, uint256 _expiry, uint256 _amount, uint256 _totalSupply, uint256 _dividendIndex); - event EtherDividendClaimed(address indexed _payee, uint256 _dividendIndex, uint256 _amount, uint256 _withheld); - event EtherDividendReclaimed(address indexed _claimer, uint256 _dividendIndex, uint256 _claimedAmount); - event EtherDividendClaimFailed(address indexed _payee, uint256 _dividendIndex, uint256 _amount, uint256 _withheld); - event EtherDividendWithholdingWithdrawn(address indexed _claimer, uint256 _dividendIndex, uint256 _withheldAmount); - - /** - * @notice Constructor - * @param _securityToken Address of the security token - * @param _polyAddress Address of the polytoken - */ - constructor (address _securityToken, address _polyAddress) public - Module(_securityToken, _polyAddress) - { - } - - /** - * @notice Creates a dividend and checkpoint for the dividend, using global list of excluded addresses - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - */ - function createDividend(uint256 _maturity, uint256 _expiry) payable external onlyOwner { - createDividendWithExclusions(_maturity, _expiry, excluded); - } - - /** - * @notice Creates a dividend with a provided checkpoint, using global list of excluded addresses - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - * @param _checkpointId Id of the checkpoint from which to issue dividend - */ - function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, uint256 _checkpointId) payable external onlyOwner { - createDividendWithCheckpointAndExclusions(_maturity, _expiry, _checkpointId, excluded); - } - - /** - * @notice Creates a dividend and checkpoint for the dividend, specifying explicit excluded addresses - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - * @param _excluded List of addresses to exclude - */ - function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address[] _excluded) payable public onlyOwner { - uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); - createDividendWithCheckpointAndExclusions(_maturity, _expiry, checkpointId, _excluded); - } - - /** - * @notice Creates a dividend with a provided checkpoint, specifying explicit excluded addresses - * @param _maturity Time from which dividend can be paid - * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer - * @param _checkpointId Id of the checkpoint from which to issue dividend - * @param _excluded List of addresses to exclude - */ - function createDividendWithCheckpointAndExclusions(uint256 _maturity, uint256 _expiry, uint256 _checkpointId, address[] _excluded) payable public onlyOwner { - require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many addresses excluded"); - require(_expiry > _maturity, "Expiry is before maturity"); - require(_expiry > now, "Expiry is in the past"); - require(msg.value > 0, "No dividend sent"); - require(_checkpointId <= ISecurityToken(securityToken).currentCheckpointId()); - uint256 dividendIndex = dividends.length; - uint256 currentSupply = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); - uint256 excludedSupply = 0; - for (uint256 i = 0; i < _excluded.length; i++) { - excludedSupply = excludedSupply.add(ISecurityToken(securityToken).balanceOfAt(_excluded[i], _checkpointId)); - } - dividends.push( - Dividend( - _checkpointId, - now, - _maturity, - _expiry, - msg.value, - 0, - currentSupply.sub(excludedSupply), - false, - 0, - 0 - ) - ); - for (uint256 j = 0; j < _excluded.length; j++) { - dividends[dividends.length - 1].dividendExcluded[_excluded[j]] = true; - } - emit EtherDividendDeposited(msg.sender, _checkpointId, now, _maturity, _expiry, msg.value, currentSupply, dividendIndex); - } - - /** - * @notice Internal function for paying dividends - * @param _payee address of investor - * @param _dividend storage with previously issued dividends - * @param _dividendIndex Dividend to pay - */ - function _payDividend(address _payee, Dividend storage _dividend, uint256 _dividendIndex) internal { - (uint256 claim, uint256 withheld) = calculateDividend(_dividendIndex, _payee); - _dividend.claimed[_payee] = true; - uint256 claimAfterWithheld = claim.sub(withheld); - if (claimAfterWithheld > 0) { - if (_payee.send(claimAfterWithheld)) { - _dividend.claimedAmount = _dividend.claimedAmount.add(claim); - _dividend.dividendWithheld = _dividend.dividendWithheld.add(withheld); - investorWithheld[_payee] = investorWithheld[_payee].add(withheld); - emit EtherDividendClaimed(_payee, _dividendIndex, claim, withheld); - } else { - _dividend.claimed[_payee] = false; - emit EtherDividendClaimFailed(_payee, _dividendIndex, claim, withheld); - } - } - } - - /** - * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends - * @param _dividendIndex Dividend to reclaim - */ - function reclaimDividend(uint256 _dividendIndex) external onlyOwner { - require(_dividendIndex < dividends.length, "Incorrect dividend index"); - require(now >= dividends[_dividendIndex].expiry, "Dividend expiry is in the future"); - require(!dividends[_dividendIndex].reclaimed, "Dividend already claimed"); - Dividend storage dividend = dividends[_dividendIndex]; - dividend.reclaimed = true; - uint256 remainingAmount = dividend.amount.sub(dividend.claimedAmount); - msg.sender.transfer(remainingAmount); - emit EtherDividendReclaimed(msg.sender, _dividendIndex, remainingAmount); - } - - /** - * @notice Allows issuer to withdraw withheld tax - * @param _dividendIndex Dividend to withdraw from - */ - function withdrawWithholding(uint256 _dividendIndex) external onlyOwner { - require(_dividendIndex < dividends.length, "Incorrect dividend index"); - Dividend storage dividend = dividends[_dividendIndex]; - uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); - dividend.dividendWithheldReclaimed = dividend.dividendWithheld; - msg.sender.transfer(remainingWithheld); - emit EtherDividendWithholdingWithdrawn(msg.sender, _dividendIndex, remainingWithheld); - } - -} +pragma solidity ^0.4.24; + +import "./DividendCheckpoint.sol"; + +/** + * @title Checkpoint module for issuing ether dividends + */ +contract EtherDividendCheckpoint is DividendCheckpoint { + using SafeMath for uint256; + + event EtherDividendDeposited(address indexed _depositor, uint256 _checkpointId, uint256 _created, uint256 _maturity, uint256 _expiry, uint256 _amount, uint256 _totalSupply, uint256 _dividendIndex, bytes32 indexed _name); + event EtherDividendClaimed(address indexed _payee, uint256 _dividendIndex, uint256 _amount, uint256 _withheld); + event EtherDividendReclaimed(address indexed _claimer, uint256 _dividendIndex, uint256 _claimedAmount); + event EtherDividendClaimFailed(address indexed _payee, uint256 _dividendIndex, uint256 _amount, uint256 _withheld); + event EtherDividendWithholdingWithdrawn(address indexed _claimer, uint256 _dividendIndex, uint256 _withheldAmount); + + /** + * @notice Constructor + * @param _securityToken Address of the security token + * @param _polyAddress Address of the polytoken + */ + constructor (address _securityToken, address _polyAddress) public + Module(_securityToken, _polyAddress) + { + } + + /** + * @notice Creates a dividend and checkpoint for the dividend, using global list of excluded addresses + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _name name/title for identification + */ + function createDividend(uint256 _maturity, uint256 _expiry, bytes32 _name) payable external onlyOwner { + createDividendWithExclusions(_maturity, _expiry, excluded, _name); + } + + /** + * @notice Creates a dividend with a provided checkpoint, using global list of excluded addresses + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _checkpointId Id of the checkpoint from which to issue dividend + * @param _name name/title for identification + */ + function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, uint256 _checkpointId, bytes32 _name) payable external onlyOwner { + _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _checkpointId, excluded, _name); + } + + /** + * @notice Creates a dividend and checkpoint for the dividend, specifying explicit excluded addresses + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _excluded List of addresses to exclude + * @param _name name/title for identification + */ + function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address[] _excluded, bytes32 _name) payable public onlyOwner { + uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); + _createDividendWithCheckpointAndExclusions(_maturity, _expiry, checkpointId, _excluded, _name); + } + + /** + * @notice Creates a dividend with a provided checkpoint, specifying explicit excluded addresses + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _checkpointId Id of the checkpoint from which to issue dividend + * @param _excluded List of addresses to exclude + * @param _name name/title for identification + */ + function createDividendWithCheckpointAndExclusions( + uint256 _maturity, + uint256 _expiry, + uint256 _checkpointId, + address[] _excluded, + bytes32 _name + ) + payable + public + onlyOwner + { + _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _checkpointId, _excluded, _name); + } + + /** + * @notice Creates a dividend with a provided checkpoint, specifying explicit excluded addresses + * @param _maturity Time from which dividend can be paid + * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer + * @param _checkpointId Id of the checkpoint from which to issue dividend + * @param _excluded List of addresses to exclude + * @param _name name/title for identification + */ + function _createDividendWithCheckpointAndExclusions( + uint256 _maturity, + uint256 _expiry, + uint256 _checkpointId, + address[] _excluded, + bytes32 _name + ) + internal + { + require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many addresses excluded"); + require(_expiry > _maturity, "Expiry is before maturity"); + require(_expiry > now, "Expiry is in the past"); + require(msg.value > 0, "No dividend sent"); + require(_checkpointId <= ISecurityToken(securityToken).currentCheckpointId()); + require(_name[0] != 0); + uint256 dividendIndex = dividends.length; + uint256 currentSupply = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); + uint256 excludedSupply = 0; + for (uint256 i = 0; i < _excluded.length; i++) { + excludedSupply = excludedSupply.add(ISecurityToken(securityToken).balanceOfAt(_excluded[i], _checkpointId)); + } + dividends.push( + Dividend( + _checkpointId, + now, + _maturity, + _expiry, + msg.value, + 0, + currentSupply.sub(excludedSupply), + false, + 0, + 0, + _name + ) + ); + for (uint256 j = 0; j < _excluded.length; j++) { + dividends[dividends.length - 1].dividendExcluded[_excluded[j]] = true; + } + emit EtherDividendDeposited(msg.sender, _checkpointId, now, _maturity, _expiry, msg.value, currentSupply, dividendIndex, _name); + } + + /** + * @notice Internal function for paying dividends + * @param _payee address of investor + * @param _dividend storage with previously issued dividends + * @param _dividendIndex Dividend to pay + */ + function _payDividend(address _payee, Dividend storage _dividend, uint256 _dividendIndex) internal { + (uint256 claim, uint256 withheld) = calculateDividend(_dividendIndex, _payee); + _dividend.claimed[_payee] = true; + uint256 claimAfterWithheld = claim.sub(withheld); + if (claimAfterWithheld > 0) { + if (_payee.send(claimAfterWithheld)) { + _dividend.claimedAmount = _dividend.claimedAmount.add(claim); + _dividend.dividendWithheld = _dividend.dividendWithheld.add(withheld); + investorWithheld[_payee] = investorWithheld[_payee].add(withheld); + emit EtherDividendClaimed(_payee, _dividendIndex, claim, withheld); + } else { + _dividend.claimed[_payee] = false; + emit EtherDividendClaimFailed(_payee, _dividendIndex, claim, withheld); + } + } + } + + /** + * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends + * @param _dividendIndex Dividend to reclaim + */ + function reclaimDividend(uint256 _dividendIndex) external onlyOwner { + require(_dividendIndex < dividends.length, "Incorrect dividend index"); + require(now >= dividends[_dividendIndex].expiry, "Dividend expiry is in the future"); + require(!dividends[_dividendIndex].reclaimed, "Dividend already claimed"); + Dividend storage dividend = dividends[_dividendIndex]; + dividend.reclaimed = true; + uint256 remainingAmount = dividend.amount.sub(dividend.claimedAmount); + msg.sender.transfer(remainingAmount); + emit EtherDividendReclaimed(msg.sender, _dividendIndex, remainingAmount); + } + + /** + * @notice Allows issuer to withdraw withheld tax + * @param _dividendIndex Dividend to withdraw from + */ + function withdrawWithholding(uint256 _dividendIndex) external onlyOwner { + require(_dividendIndex < dividends.length, "Incorrect dividend index"); + Dividend storage dividend = dividends[_dividendIndex]; + uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); + dividend.dividendWithheldReclaimed = dividend.dividendWithheld; + msg.sender.transfer(remainingWithheld); + emit EtherDividendWithholdingWithdrawn(msg.sender, _dividendIndex, remainingWithheld); + } + +} diff --git a/contracts/modules/Checkpoint/ICheckpoint.sol b/contracts/modules/Checkpoint/ICheckpoint.sol index 214093131..3e567ba7b 100644 --- a/contracts/modules/Checkpoint/ICheckpoint.sol +++ b/contracts/modules/Checkpoint/ICheckpoint.sol @@ -1,8 +1,8 @@ -pragma solidity ^0.4.24; - -/** - * @title Interface to be implemented by all checkpoint modules - */ -interface ICheckpoint { - -} +pragma solidity ^0.4.24; + +/** + * @title Interface to be implemented by all checkpoint modules + */ +interface ICheckpoint { + +} diff --git a/contracts/oracles/MakerDAOOracle.sol b/contracts/oracles/MakerDAOOracle.sol index ab7795007..63d8b73cb 100644 --- a/contracts/oracles/MakerDAOOracle.sol +++ b/contracts/oracles/MakerDAOOracle.sol @@ -13,9 +13,9 @@ contract MakerDAOOracle is IOracle, Ownable { bool public manualOverride; uint256 public manualPrice; - event LogChangeMedianizer(address _newMedianizer, address _oldMedianizer, uint256 _now); - event LogSetManualPrice(uint256 _oldPrice, uint256 _newPrice, uint256 _time); - event LogSetManualOverride(bool _override, uint256 _time); + event ChangeMedianizer(address _newMedianizer, address _oldMedianizer, uint256 _now); + event SetManualPrice(uint256 _oldPrice, uint256 _newPrice, uint256 _time); + event SetManualOverride(bool _override, uint256 _time); /** * @notice Creates a new Maker based oracle @@ -35,7 +35,7 @@ contract MakerDAOOracle is IOracle, Ownable { */ function changeMedianier(address _medianizer) public onlyOwner { require(_medianizer != address(0), "0x not allowed"); - emit LogChangeMedianizer(_medianizer, medianizer, now); + emit ChangeMedianizer(_medianizer, medianizer, now); medianizer = _medianizer; } @@ -78,7 +78,7 @@ contract MakerDAOOracle is IOracle, Ownable { * @param _price Price to set */ function setManualPrice(uint256 _price) public onlyOwner { - emit LogSetManualPrice(manualPrice, _price, now); + emit SetManualPrice(manualPrice, _price, now); manualPrice = _price; } @@ -88,7 +88,7 @@ contract MakerDAOOracle is IOracle, Ownable { */ function setManualOverride(bool _override) public onlyOwner { manualOverride = _override; - emit LogSetManualOverride(_override, now); + emit SetManualOverride(_override, now); } } diff --git a/contracts/oracles/PolyOracle.sol b/contracts/oracles/PolyOracle.sol index e5328ea74..005d1677b 100644 --- a/contracts/oracles/PolyOracle.sol +++ b/contracts/oracles/PolyOracle.sol @@ -26,10 +26,10 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { bool public freezeOracle; - event LogPriceUpdated(uint256 _price, uint256 _oldPrice, bytes32 _queryId, uint256 _time); - event LogNewOraclizeQuery(uint256 _time, bytes32 _queryId, string _query); - event LogAdminSet(address _admin, bool _valid, uint256 _time); - event LogStalePriceUpdate(bytes32 _queryId, uint256 _time, string _result); + event PriceUpdated(uint256 _price, uint256 _oldPrice, bytes32 _queryId, uint256 _time); + event NewOraclizeQuery(uint256 _time, bytes32 _queryId, string _query); + event AdminSet(address _admin, bool _valid, uint256 _time); + event StalePriceUpdate(bytes32 _queryId, uint256 _time, string _result); modifier isAdminOrOwner { require(admin[msg.sender] || msg.sender == owner, "Address is not admin or owner"); @@ -55,7 +55,7 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { require(!ignoreRequestIds[_requestId], "Ignoring requestId"); if (requestIds[_requestId] < latestUpdate) { // Result is stale, probably because it was received out of order - emit LogStalePriceUpdate(_requestId, requestIds[_requestId], _result); + emit StalePriceUpdate(_requestId, requestIds[_requestId], _result); return; } require(requestIds[_requestId] >= latestUpdate, "Result is stale"); @@ -67,7 +67,7 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { require(newPOLYUSD >= POLYUSD.sub(bound), "Result is too small"); } latestUpdate = requestIds[_requestId]; - emit LogPriceUpdated(newPOLYUSD, POLYUSD, _requestId, latestUpdate); + emit PriceUpdated(newPOLYUSD, POLYUSD, _requestId, latestUpdate); POLYUSD = newPOLYUSD; } @@ -83,7 +83,7 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { requestId = oraclize_query(oracleQueryType, oracleURL, gasLimit); requestIds[requestId] = now; maximumScheduledUpdated = now; - emit LogNewOraclizeQuery(now, requestId, oracleURL); + emit NewOraclizeQuery(now, requestId, oracleURL); } else { require(oraclize_getPrice(oracleQueryType, gasLimit) * _times.length <= address(this).balance, "Insufficient Funds"); for (uint256 i = 0; i < _times.length; i++) { @@ -93,7 +93,7 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { if (maximumScheduledUpdated < requestIds[requestId]) { maximumScheduledUpdated = requestIds[requestId]; } - emit LogNewOraclizeQuery(_times[i], requestId, oracleURL); + emit NewOraclizeQuery(_times[i], requestId, oracleURL); } } if (latestScheduledUpdate < maximumScheduledUpdated) { @@ -117,7 +117,7 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { uint256 scheduledTime = _startTime + (i * _interval); requestId = oraclize_query(scheduledTime, oracleQueryType, oracleURL, gasLimit); requestIds[requestId] = scheduledTime; - emit LogNewOraclizeQuery(scheduledTime, requestId, oracleURL); + emit NewOraclizeQuery(scheduledTime, requestId, oracleURL); } if (latestScheduledUpdate < requestIds[requestId]) { latestScheduledUpdate = requestIds[requestId]; @@ -129,7 +129,7 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { * @param _price POLYUSD price */ function setPOLYUSD(uint256 _price) onlyOwner public { - emit LogPriceUpdated(_price, POLYUSD, 0, now); + emit PriceUpdated(_price, POLYUSD, 0, now); POLYUSD = _price; latestUpdate = now; } @@ -220,7 +220,7 @@ contract PolyOracle is usingOraclize, IOracle, Ownable { */ function setAdmin(address _admin, bool _valid) onlyOwner public { admin[_admin] = _valid; - emit LogAdminSet(_admin, _valid, now); + emit AdminSet(_admin, _valid, now); } /** diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 2622d7fb5..c61d42b5c 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -149,7 +149,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr event ForceBurn(address indexed _controller, address indexed _from, uint256 _value, bool _verifyTransfer, bytes _data); event DisableController(uint256 _timestamp); - function isModule(address _module, uint8 _type) internal view returns (bool) { + function _isModule(address _module, uint8 _type) internal view returns (bool) { require(modulesToData[_module].module == _module, "Address mismatch"); require(modulesToData[_module].moduleType[_type], "Type mismatch"); require(!modulesToData[_module].isArchived, "Module archived"); @@ -158,7 +158,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // Require msg.sender to be the specified module type modifier onlyModule(uint8 _type) { - require(isModule(msg.sender, _type)); + require(_isModule(msg.sender, _type)); _; } @@ -167,7 +167,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr if (msg.sender == owner) { _; } else { - require(isModule(msg.sender, _type)); + require(_isModule(msg.sender, _type)); _; } } @@ -677,6 +677,29 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return true; } + /** + * @notice Validate permissions with PermissionManager if it exists, If no Permission return false + * @dev Note that IModule withPerm will allow ST owner all permissions anyway + * @dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions) + * @param _delegate address of delegate + * @param _module address of PermissionManager module + * @param _perm the permissions + * @return success + */ + function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) { + if (modules[PERMISSIONMANAGER_KEY].length == 0) { + return false; + } + + for (uint8 i = 0; i < modules[PERMISSIONMANAGER_KEY].length; i++) { + if (IPermissionManager(modules[PERMISSIONMANAGER_KEY][i]).checkPermission(_delegate, _module, _perm)) { + return true; + } + } + + return false; + } + function _burn(address _from, uint256 _value) internal returns (bool) { require(_value <= balances[_from], "Value too high"); require(_updateTransfer(_from, address(0), _value), "Burn is not valid"); @@ -721,27 +744,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return currentCheckpointId; } - /** - * @notice Validate permissions with PermissionManager if it exists, If no Permission return false - * @dev Note that IModule withPerm will allow ST owner all permissions anyway - * @dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions) - * @param _delegate address of delegate - * @param _module address of PermissionManager module - * @param _perm the permissions - * @return success - */ - function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) { - if (modules[PERMISSION_KEY].length == 0) { - return false; - } - - for (uint8 i = 0; i < modules[PERMISSION_KEY].length; i++) { - if (IPermissionManager(modules[PERMISSION_KEY][i]).checkPermission(_delegate, _module, _perm)) { - return true; - } - } - } - /** * @notice Gets list of times that checkpoints were created * @return List of checkpoint times diff --git a/scripts/test.sh b/scripts/test.sh index d6fb7a632..d24ce6b0f 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Global variable +# Global variable bridge_pid # Exit script as soon as a command fails. @@ -63,9 +63,9 @@ start_testrpc() { if ! [ -z "${TRAVIS_PULL_REQUEST+x}" ] && [ "$TRAVIS_PULL_REQUEST" != false ]; then node_modules/.bin/testrpc-sc --gasLimit 0xfffffffffff --port "$testrpc_port" "${accounts[@]}" > /dev/null & else - node_modules/.bin/ganache-cli --gasLimit 0xfffffffffff "${accounts[@]}" > /dev/null & + node_modules/.bin/ganache-cli --gasLimit 8000000 "${accounts[@]}" > /dev/null & fi - + testrpc_pid=$! } diff --git a/test/a_poly_oracle.js b/test/a_poly_oracle.js index 9eb6c9b56..f727b4014 100644 --- a/test/a_poly_oracle.js +++ b/test/a_poly_oracle.js @@ -84,9 +84,9 @@ let requestIds = new Array(); let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); // await increaseTime(50); - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.LogPriceUpdated({ fromBlock: blockNo }), 1); + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); // const log = await logNewPriceWatcher; - assert.equal(logNewPriceWatcher.event, 'LogPriceUpdated', 'LogPriceUpdated not emitted.') + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') assert.equal(logNewPriceWatcher.args._oldPrice.toNumber(), 0); console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') @@ -107,9 +107,9 @@ let requestIds = new Array(); } // Wait for the callback to be invoked by oraclize and the event to be emitted - const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.LogPriceUpdated({ fromBlock: blockNo }), 2); + const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); const log = await logNewPriceWatcher; - assert.equal(log.event, 'LogPriceUpdated', 'LogPriceUpdated not emitted.') + assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') assert.isNotNull(log.args._price, 'Price returned was null.'); console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') }); @@ -137,9 +137,9 @@ let requestIds = new Array(); assert.isAtMost(time.toNumber(), latestTime() + ((i + 1) * 30)); } // Wait for the callback to be invoked by oraclize and the event to be emitted - const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.LogPriceUpdated({ fromBlock: blockNo }), 2); + const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); const log = await logNewPriceWatcher; - assert.equal(log.event, 'LogPriceUpdated', 'LogPriceUpdated not emitted.') + assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') assert.isNotNull(log.args._price, 'Price returned was null.') console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); latestPrice = log.args._price; @@ -229,9 +229,9 @@ let requestIds = new Array(); assert.isAtMost(time.toNumber(), timeScheduling[i]); } - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.LogPriceUpdated({ fromBlock: blockNo }), 2); + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - assert.equal(logNewPriceWatcher.event, 'LogPriceUpdated', 'LogPriceUpdated not emitted.') + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); // assert.isTrue(false); @@ -319,8 +319,8 @@ let requestIds = new Array(); let blockNo = latestBlock(); let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.LogPriceUpdated({ fromBlock: blockNo }), 1); - assert.equal(logNewPriceWatcher.event, 'LogPriceUpdated', 'LogPriceUpdated not emitted.') + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); // assert.isTrue(false); diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 11a797933..ec216c637 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -258,7 +258,7 @@ contract('CappedSTO', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); @@ -298,7 +298,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); } catch(error) { console.log(` tx revert -> Rate is ${0}. Test Passed Successfully`.grey); errorThrown = true; @@ -315,7 +315,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); } catch(error) { console.log(`Tx Failed because of rate is ${0}. Test Passed Successfully`); errorThrown = true; @@ -328,7 +328,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [ Math.floor(Date.now()/1000 + 100000), Math.floor(Date.now()/1000 + 1000), cap, rate, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); } catch(error) { errorThrown = true; console.log(` tx revert -> StartTime is greater than endTime. Test Passed Successfully`.grey); @@ -343,7 +343,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [ startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); } catch(error) { console.log(`Tx Failed because the Cap is equal to ${0}. Test Passed Successfully`); errorThrown = true; @@ -356,7 +356,7 @@ contract('CappedSTO', accounts => { startTime_ETH1 = latestTime() + duration.days(1); endTime_ETH1 = startTime_ETH1 + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver]); - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 45000000 }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); @@ -876,7 +876,7 @@ contract('CappedSTO', accounts => { it("POLY: Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, { from: token_owner, gas:85000000 }); + let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, P_symbol, "SecurityToken doesn't get deployed"); @@ -904,7 +904,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY1, endTime_POLY1, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); @@ -1262,7 +1262,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY2, endTime_POLY2, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index d40996a66..a9094c6c5 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -205,7 +205,7 @@ contract('Checkpoints', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 4b65e249a..75c938939 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -247,7 +247,7 @@ contract('CountTransferManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 82125d688..cdd1fa98d 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -41,6 +41,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiryTime = toTime + duration.days(15); let message = "Transaction Should Fail!"; + let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; // Contract Instance Declaration let I_GeneralPermissionManagerFactory; @@ -239,7 +240,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); @@ -364,7 +365,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because allowance = 0`.grey); ensureException(error); @@ -379,7 +380,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() - duration.days(10); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because maturity > expiry`.grey); ensureException(error); @@ -393,7 +394,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because now > expiry`.grey); ensureException(error); @@ -407,7 +408,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because token address is 0x`.grey); ensureException(error); @@ -421,7 +422,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because amount < 0`.grey); ensureException(error); @@ -434,8 +435,9 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); + assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); }); it("Investor 1 transfers his token balance to investor 2", async() => { @@ -519,12 +521,28 @@ contract('ERC20DividendCheckpoint', accounts => { ); }); - it("Create new dividend", async() => { + it("Should not allow to create dividend without name", async() => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + let errorThrown = false; + try { + await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because dividend name is empty`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Create new dividend", async() => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + // approved in above test + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 1"); }); @@ -589,7 +607,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), dividendName, {from: token_owner}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 2"); }); @@ -676,7 +694,7 @@ contract('ERC20DividendCheckpoint', accounts => { console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, {from: token_owner}); + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because allowance is not provided`.grey); ensureException(error); @@ -693,7 +711,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() - duration.days(10); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), {from: token_owner}); try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, {from: token_owner}); + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because maturity > expiry`.grey); ensureException(error); @@ -709,7 +727,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, {from: token_owner}); + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because now > expiry`.grey); ensureException(error); @@ -723,7 +741,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, {from: token_owner}); + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because checkpoint id > current checkpoint`.grey); ensureException(error); @@ -741,7 +759,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); - let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, [account_investor1], {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, [account_investor1], dividendName, {from: token_owner}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 3"); }); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 0e7468075..dec4be72f 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -41,6 +41,7 @@ contract('EtherDividendCheckpoint', accounts => { let expiryTime = toTime + duration.days(15); let message = "Transaction Should Fail!"; + let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; // Contract Instance Declaration let I_GeneralPermissionManagerFactory; @@ -239,7 +240,7 @@ contract('EtherDividendCheckpoint', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); @@ -364,7 +365,7 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); try { - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, {from: token_owner}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner}); } catch(error) { console.log(` tx -> failed because msg.value = 0`.grey); ensureException(error); @@ -378,7 +379,7 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() - duration.days(10); try { - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); } catch(error) { console.log(` tx -> failed because maturity > expiry`.grey); ensureException(error); @@ -392,7 +393,7 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); try { - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); } catch(error) { console.log(` tx -> failed because now > expiry`.grey); ensureException(error); @@ -405,11 +406,26 @@ contract('EtherDividendCheckpoint', accounts => { await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(20*10**16), {from: token_owner}); }); + it("Should fail in creating the dividend", async() => { + let errorThrown = false; + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + try { + await I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + } catch(error) { + console.log(` tx -> failed because dividend name is empty`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + it("Create new dividend", async() => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); + assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); }); it("Investor 1 transfers his token balance to investor 2", async() => { @@ -510,7 +526,7 @@ contract('EtherDividendCheckpoint', accounts => { it("Create new dividend", async() => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 2"); }); @@ -576,7 +592,7 @@ contract('EtherDividendCheckpoint', accounts => { it("Create another new dividend", async() => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 3"); }); @@ -662,7 +678,7 @@ contract('EtherDividendCheckpoint', accounts => { let expiry = latestTime() + duration.days(2); let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, {from: token_owner, value: 0}); + tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: 0}); } catch(error) { console.log(` tx -> failed because msg.value is 0`.grey); ensureException(error); @@ -676,7 +692,7 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() - duration.days(10); try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); + tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); } catch(error) { console.log(` tx -> failed because maturity > expiry`.grey); ensureException(error); @@ -690,7 +706,7 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); + tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); } catch(error) { console.log(` tx -> failed because now > expiry`.grey); ensureException(error); @@ -704,7 +720,7 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); + tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); } catch(error) { console.log(` tx -> failed because checkpoint id > current checkpoint`.grey); ensureException(error); @@ -717,7 +733,7 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, [account_investor1], {from: token_owner, value: web3.utils.toWei('10', 'ether')}); + tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, [account_investor1], dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 4"); }); @@ -890,7 +906,7 @@ contract('EtherDividendCheckpoint', accounts => { it("Create another new dividend", async() => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], {from: token_owner, value: web3.utils.toWei('12', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], dividendName, {from: token_owner, value: web3.utils.toWei('12', 'ether')}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 6, "Dividend should be created at checkpoint 6"); }); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 6e483d203..3b7299ca2 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -254,7 +254,7 @@ contract('GeneralPermissionManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 190ab54ad..36eccdbb0 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -241,7 +241,7 @@ contract('GeneralTransferManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 78953fa24..9036435f8 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -255,7 +255,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index bc728259f..a7ed18719 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -384,7 +384,7 @@ contract('ModuleRegistry', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); let errorThrown = false; try { - const tx = await I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner, gas: 60000000 }); + const tx = await I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner}); } catch(error) { errorThrown = true; console.log(` tx revert -> Module is un-verified`.grey); @@ -426,7 +426,7 @@ contract('ModuleRegistry', accounts => { endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); - tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner, gas: 60000000 }); + tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner}); assert.equal(tx.logs[2].args._type, stoKey, "CappedSTO doesn't get deployed"); assert.equal( diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 92504c4c2..4e81888f4 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -249,7 +249,7 @@ contract('PercentageTransferManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index acc04642d..862885bcf 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -229,7 +229,7 @@ contract('PreSaleSTO', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); @@ -256,7 +256,7 @@ contract('PreSaleSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [0]); let errorThrown = false; try { - const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); } catch(error) { console.log(` tx revert -> Rate is ${0}. Test Passed Successfully`.grey); errorThrown = true; @@ -269,7 +269,7 @@ contract('PreSaleSTO', accounts => { endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time let bytesSTO = encodeModuleCall(STOParameters, [endTime]); - const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner, gas: 26000000 }); + const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._type, stoKey, "PreSaleSTO doesn't get deployed"); assert.equal( @@ -333,7 +333,7 @@ contract('PreSaleSTO', accounts => { // Jump time await increaseTime(duration.days(1)); - await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_issuer, gas: 60000000}); + await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_issuer }); assert.equal( (await I_PreSaleSTO.getRaised.call(0)) @@ -350,7 +350,7 @@ contract('PreSaleSTO', accounts => { it("Should allocate the tokens -- failed due to msg.sender is not pre sale admin", async () => { let errorThrown = false; try { - await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver, gas: 60000000}); + await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver }); } catch(error) { console.log(` tx revert -> msg.sender is not pre sale admin`.grey); errorThrown = true; @@ -392,7 +392,7 @@ contract('PreSaleSTO', accounts => { assert.equal(tx2.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); - await I_PreSaleSTO.allocateTokensMulti([account_investor2, account_investor3], [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], [0,0], [web3.utils.toWei('1000', 'ether'), web3.utils.toWei('1000', 'ether')], {from: account_issuer, gas: 60000000}); + await I_PreSaleSTO.allocateTokensMulti([account_investor2, account_investor3], [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], [0,0], [web3.utils.toWei('1000', 'ether'), web3.utils.toWei('1000', 'ether')], {from: account_issuer }); assert.equal( (await I_PreSaleSTO.getRaised.call(1)) diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index e51bea0bd..69d9623ad 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -485,7 +485,7 @@ contract('SecurityTokenRegistry', accounts => { let errorThrown = false; await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner}); try { - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); } catch(error) { console.log(` tx revert -> POLY allowance not provided for registration fee`.grey); errorThrown = true; @@ -499,7 +499,7 @@ contract('SecurityTokenRegistry', accounts => { await I_STRProxied.pause({ from: account_polymath}); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); try { - await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); } catch(error) { console.log(` tx revert -> Registration is paused`.grey); errorThrown = true; @@ -512,7 +512,7 @@ contract('SecurityTokenRegistry', accounts => { let errorThrown = false; await I_STRProxied.unpause({ from: account_polymath}); try { - await I_STRProxied.generateSecurityToken(name, "", tokenDetails, false, { from: token_owner, gas:60000000 }); + await I_STRProxied.generateSecurityToken(name, "", tokenDetails, false, { from: token_owner }); } catch(error) { console.log(` tx revert -> Zero ticker length is not allowed`.grey); errorThrown = true; @@ -524,7 +524,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should fail to generate the securityToken -- Because name length is 0", async() => { let errorThrown = false; try { - await I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + await I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: token_owner }); } catch(error) { console.log(` tx revert -> 0 name length is not allowed`.grey); errorThrown = true; @@ -536,7 +536,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker", async() => { let errorThrown = false; try { - await I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp, gas:60000000 }); + await I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp }); } catch(error) { console.log(` tx revert -> Because msg.sender is not the rightful owner of the ticker`.grey); errorThrown = true; @@ -547,7 +547,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); @@ -568,7 +568,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should fail to generate the SecurityToken when token is already deployed with the same symbol", async() => { let errorThrown = false; try { - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); } catch(error) { console.log(` tx revert -> Because ticker is already in use`.grey); errorThrown = true; @@ -608,7 +608,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should generate the new security token with version 2", async() => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, { from: token_owner, gas:60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); @@ -739,9 +739,15 @@ contract('SecurityTokenRegistry', accounts => { // Register the new ticker -- Fulfiling the TickerStatus.ON condition await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); + let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); await I_STRProxied.registerTicker(account_temp, "LOG", "LOGAN", { from : account_temp }); + tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); // Generating the ST let tx = await I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); + tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); assert.equal(tx.logs[1].args._ticker, "LOG", "Symbol should match with the registered symbol"); assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token,`Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); let symbolDetails = await I_STRProxied.getTickerDetails("LOG"); @@ -751,6 +757,17 @@ contract('SecurityTokenRegistry', accounts => { it("Should successfully generate the custom token", async() => { // Fulfilling the TickerStatus.NN condition + // let errorThrown = false; + // try { + // await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); + // } catch(error) { + // console.log(` tx revert -> because ticker not registered`.grey); + // errorThrown = true; + // ensureException(error); + // } + // assert.ok(errorThrown, message); + // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); + // await increaseTime(duration.days(1)); let tx = await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); assert.equal(tx.logs[1].args._ticker, "LOG2", "Symbol should match with the registered symbol"); assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token, `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); @@ -833,8 +850,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should change the details of the existing ticker", async() => { let tx = await I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); - assert.equal(tx.logs[0].args._oldOwner, account_temp); - assert.equal(tx.logs[0].args._newOwner, token_owner); + assert.equal(tx.logs[0].args._owner, token_owner); }); }); @@ -1014,7 +1030,7 @@ contract('SecurityTokenRegistry', accounts => { let errorThrown = false; await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); try { - await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner, gas:60000000 }); + await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }); } catch(error) { console.log(` tx revert -> failed because of old launch fee`.grey); errorThrown = true; @@ -1025,7 +1041,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should launch the the securityToken", async() => { await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner}); - let tx = await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner, gas:60000000 }); + let tx = await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, "POLY", "SecurityToken doesn't get deployed"); @@ -1083,7 +1099,8 @@ contract('SecurityTokenRegistry', accounts => { let tickersList = await I_STRProxied.getTickersByOwner.call(token_owner); assert.equal(tickersList.length, 4); let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - assert.equal(tickersListArray.length, 2); + console.log(tickersListArray); + assert.equal(tickersListArray.length, 3); }); }); @@ -1120,6 +1137,58 @@ contract('SecurityTokenRegistry', accounts => { }); }) + describe(" Test cases of the registerTicker", async() => { + + it("Should register the ticker 1", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + let tx = await I_STRProxied.registerTicker(account_temp, "TOK1", "", { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK1", `Symbol should be TOK1`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + }); + + it("Should register the ticker 2", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + let tx = await I_STRProxied.registerTicker(account_temp, "TOK2", "", { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK2", `Symbol should be TOK2`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + }); + + it("Should register the ticker 3", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + let tx = await I_STRProxied.registerTicker(account_temp, "TOK3", "", { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK3", `Symbol should be TOK3`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + }); + + it("Should successfully remove the ticker 2", async() => { + let tx = await I_STRProxied.removeTicker("TOK2", {from: account_polymath}); + assert.equal(tx.logs[0].args._ticker, "TOK2", "Ticker doesn't get deleted successfully"); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + }); + + it("Should modify ticker 1", async() => { + let tx = await I_STRProxied.modifyTicker(account_temp, "TOK1", "TOKEN 1", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK1", "Should be equal to TOK1"); + assert.equal(tx.logs[0].args._name, "TOKEN 1", "Should be equal to TOKEN 1"); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + }) + + it("Should modify ticker 3", async() => { + let tx = await I_STRProxied.modifyTicker(account_temp, "TOK3", "TOKEN 3", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK3", "Should be equal to TOK3"); + assert.equal(tx.logs[0].args._name, "TOKEN 3", "Should be equal to TOKEN 3"); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + }) + + }); describe("Test cases for IRegistry functionality", async() => { describe("Test cases for reclaiming funds", async() => { diff --git a/test/o_security_token.js b/test/o_security_token.js index caaade82c..1217c6c22 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -255,7 +255,7 @@ contract('SecurityToken', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); @@ -444,7 +444,7 @@ contract('SecurityToken', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); let errorThrown = false; try { - let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner, gas: 60000000 }); + let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); } catch (error) { console.log(` tx revert -> not enough poly in contract`); errorThrown = true; @@ -461,7 +461,7 @@ contract('SecurityToken', accounts => { await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: token_owner}); let errorThrown = false; try { - let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner, gas: 60000000 }); + let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner }); } catch (error) { console.log(` tx revert -> max cost too small`); errorThrown = true; @@ -478,7 +478,7 @@ 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, gas: 60000000 }); + const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.toUtf8(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); diff --git a/test/r_concurrent_STO.js b/test/r_concurrent_STO.js index c86d53a43..f01a36436 100644 --- a/test/r_concurrent_STO.js +++ b/test/r_concurrent_STO.js @@ -239,7 +239,7 @@ contract('Concurrent STO', accounts => { await I_PolyToken.getTokens(initRegFee, account_issuer); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer}); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_issuer, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_issuer }); assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 2dcafde5c..2666f7158 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -185,7 +185,7 @@ contract ("SecurityTokenRegistryProxy", accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index fe03a8614..95f3303ae 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -227,7 +227,7 @@ contract('TrackedRedemption', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); From 59cb476826a433618fe999ca8800b24c1f150d6e Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Tue, 2 Oct 2018 22:16:50 +0100 Subject: [PATCH 011/142] Size too big... --- contracts/SecurityTokenRegistry.sol | 2 +- contracts/tokens/SecurityToken.sol | 6 +++--- test/b_capped_sto.js | 2 +- test/d_count_transfer_manager.js | 2 +- test/e_erc20_dividends.js | 2 +- test/f_ether_dividends.js | 2 +- test/g_general_permission_manager.js | 2 +- test/h_general_transfer_manager.js | 4 ++-- test/j_manual_approval_transfer_manager.js | 2 +- test/l_percentage_transfer_manager.js | 2 +- test/m_presale_sto.js | 2 +- test/p_usd_tiered_sto.js | 2 +- test/v_tracked_redemptions.js | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index 438e2eef5..8f2229b59 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -278,7 +278,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { return true; } - function _tickerStatus(string _ticker) internal returns(bool) { + function _tickerStatus(string _ticker) internal view returns(bool) { return getBool(Encoder.getKey("registeredTickers_status", _ticker)); } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index c61d42b5c..40b032f67 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -687,12 +687,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return success */ function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) { - if (modules[PERMISSIONMANAGER_KEY].length == 0) { + if (modules[PERMISSION_KEY].length == 0) { return false; } - for (uint8 i = 0; i < modules[PERMISSIONMANAGER_KEY].length; i++) { - if (IPermissionManager(modules[PERMISSIONMANAGER_KEY][i]).checkPermission(_delegate, _module, _perm)) { + for (uint8 i = 0; i < modules[PERMISSION_KEY].length; i++) { + if (IPermissionManager(modules[PERMISSION_KEY][i]).checkPermission(_delegate, _module, _perm)) { return true; } } diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index ec216c637..a07d6b864 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -1102,7 +1102,7 @@ contract('CappedSTO', accounts => { describe("Test cases for the CappedSTOFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_CappedSTOFactory.setupCost.call()).toNumber(), cappedSTOSetupCost); - assert.equal(await I_CappedSTOFactory.getType.call(),3); + assert.equal(await I_CappedSTOFactory.getTypes.call(0),3); assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), "CappedSTO", "Wrong Module added"); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 75c938939..0e588a068 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -477,7 +477,7 @@ contract('CountTransferManager', accounts => { describe("Test cases for the factory", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_CountTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_CountTransferManagerFactory.getType.call(),2); + assert.equal(await I_CountTransferManagerFactory.getTypes.call(0),2); assert.equal(web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()) .replace(/\u0000/g, ''), "CountTransferManager", diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index cdd1fa98d..b2d34f577 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -938,7 +938,7 @@ contract('ERC20DividendCheckpoint', accounts => { describe("Test cases for the ERC20DividendCheckpointFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_ERC20DividendCheckpointFactory.getTypes.call(0), 4); assert.equal(web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()) .replace(/\u0000/g, ''), "ERC20DividendCheckpoint", diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index dec4be72f..c31197c0a 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -958,7 +958,7 @@ contract('EtherDividendCheckpoint', accounts => { describe("Test cases for the EtherDividendCheckpointFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_EtherDividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_EtherDividendCheckpointFactory.getTypes.call(0), 4); assert.equal(web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()) .replace(/\u0000/g, ''), "EtherDividendCheckpoint", diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 3b7299ca2..da5a8a3f1 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -398,7 +398,7 @@ contract('GeneralPermissionManager', accounts => { describe("General Permission Manager Factory test cases", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); - assert.equal(await I_GeneralPermissionManagerFactory.getType.call(),1); + assert.equal(await I_GeneralPermissionManagerFactory.getTypes.call(0),1); assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) .replace(/\u0000/g, ''), "GeneralPermissionManager", diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 36eccdbb0..76b4be249 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -791,7 +791,7 @@ contract('GeneralTransferManager', accounts => { it("Should get the exact details of the factory", async() => { assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_GeneralTransferManagerFactory.getType.call(),2); + assert.equal(await I_GeneralTransferManagerFactory.getTypes.call(0),2); assert.equal(web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()) .replace(/\u0000/g, ''), "GeneralTransferManager", @@ -817,7 +817,7 @@ contract('GeneralTransferManager', accounts => { describe("Dummy STO Factory test cases", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_DummySTOFactory.setupCost.call(),0); - assert.equal(await I_DummySTOFactory.getType.call(),3); + assert.equal(await I_DummySTOFactory.getTypes.call(0),3); assert.equal(web3.utils.toAscii(await I_DummySTOFactory.getName.call()) .replace(/\u0000/g, ''), "DummySTO", diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 9036435f8..4a1a6bd5c 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -691,7 +691,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Should get the exact details of the factory", async() => { assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_ManualApprovalTransferManagerFactory.getType.call(),2); + assert.equal(await I_ManualApprovalTransferManagerFactory.getTypes.call(0),2); let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); assert.equal(name,"ManualApprovalTransferManager","Wrong Module added"); let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 4e81888f4..92e9e3a46 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -459,7 +459,7 @@ contract('PercentageTransferManager', accounts => { it("Should get the exact details of the factory", async() => { assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_PercentageTransferManagerFactory.getType.call(),2); + assert.equal(await I_PercentageTransferManagerFactory.getTypes.call(0),2); assert.equal(web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()) .replace(/\u0000/g, ''), "PercentageTransferManager", diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index 862885bcf..ad5482b35 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -455,7 +455,7 @@ contract('PreSaleSTO', accounts => { describe("Test cases for the PresaleSTOFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_PreSaleSTOFactory.setupCost.call(),0); - assert.equal(await I_PreSaleSTOFactory.getType.call(),3); + assert.equal(await I_PreSaleSTOFactory.getTypes.call(0),3); assert.equal(web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()) .replace(/\u0000/g, ''), "PreSaleSTO", diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 1acc0ef7d..79270063b 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -3493,7 +3493,7 @@ contract('USDTieredSTO', accounts => { describe("Test cases for the USDTieredSTOFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_USDTieredSTOFactory.setupCost.call()).toNumber(), STOSetupCost); - assert.equal(await I_USDTieredSTOFactory.getType.call(),3); + assert.equal(await I_USDTieredSTOFactory.getTypes.call(0),3); assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), "USDTieredSTO", "Wrong Module added"); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 95f3303ae..634eb31e2 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -354,7 +354,7 @@ contract('TrackedRedemption', accounts => { describe("Test cases for the TrackedRedemptionFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_TrackedRedemptionFactory.getType.call(), 5); + assert.equal(await I_TrackedRedemptionFactory.getTypes.call(0), 5); assert.equal(web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()) .replace(/\u0000/g, ''), "TrackedRedemption", From f7741132cd4f933b9709138ae9fdb51e98b38419 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Wed, 3 Oct 2018 11:41:46 +0530 Subject: [PATCH 012/142] Added exception helper --- test/helpers/exceptions.js | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/helpers/exceptions.js diff --git a/test/helpers/exceptions.js b/test/helpers/exceptions.js new file mode 100644 index 000000000..c5fb6f45e --- /dev/null +++ b/test/helpers/exceptions.js @@ -0,0 +1,44 @@ +const PREFIX = 'VM Exception while processing transaction: '; + +async function tryCatch(promise, message, reason) { + try { + await promise; + throw null; + } catch (error) { + assert(error, 'Expected an error but did not get one'); + assert( + error.message.startsWith(PREFIX + message), + "Expected an error starting with '" + + PREFIX + + message + + "' but got '" + + error.message + + "' instead" + ); + console.log(reason); + } +} + +module.exports = { + catchRevert: async function(promise, reason) { + await tryCatch(promise, 'revert', reason); + }, + catchOutOfGas: async function(promise, reason) { + await tryCatch(promise, 'out of gas', reason); + }, + catchInvalidJump: async function(promise, reason) { + await tryCatch(promise, 'invalid JUMP', reason); + }, + catchInvalidOpcode: async function(promise, reason) { + await tryCatch(promise, 'invalid opcode', reason); + }, + catchStackOverflow: async function(promise, reason) { + await tryCatch(promise, 'stack overflow', reason); + }, + catchStackUnderflow: async function(promise, reason) { + await tryCatch(promise, 'stack underflow', reason); + }, + catchStaticStateChange: async function(promise, reason) { + await tryCatch(promise, 'static state change', reason); + } +}; \ No newline at end of file From b197574ab7613d85ba4f6aeeda9b93c22b281a87 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Wed, 3 Oct 2018 13:46:12 +0530 Subject: [PATCH 013/142] Using helper in erc20 dividend tests --- .../modules/Checkpoint/DividendCheckpoint.sol | 2 +- test/e_erc20_dividends.js | 341 ++++++------------ 2 files changed, 111 insertions(+), 232 deletions(-) diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index fc70a9fde..716ab5d1f 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -50,9 +50,9 @@ contract DividendCheckpoint is ICheckpoint, Module { modifier validDividendIndex(uint256 _dividendIndex) { require(_dividendIndex < dividends.length, "Incorrect dividend index"); + require(!dividends[_dividendIndex].reclaimed, "Dividend has been reclaimed by issuer"); require(now >= dividends[_dividendIndex].maturity, "Dividend maturity is in the future"); require(now < dividends[_dividendIndex].expiry, "Dividend expiry is in the past"); - require(!dividends[_dividendIndex].reclaimed, "Dividend has been reclaimed by issuer"); _; } diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index cdd1fa98d..e45808916 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -264,15 +265,10 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment", async () => { - let errorThrown = false; - try { - const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }), + "tx -> failed because Token is not paid" + ); }); it("Should successfully attach the ERC20DividendCheckpoint with the security token with budget", async () => { @@ -360,75 +356,50 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Should fail in creating the dividend - incorrect allowance", async() => { - let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because allowance = 0`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because allowance = 0" + ); }); it("Should fail in creating the dividend - maturity > expiry", async() => { - let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() - duration.days(10); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); - try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because maturity > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because maturity > expiry" + ); }); it("Should fail in creating the dividend - now > expiry", async() => { - let errorThrown = false; let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); - try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because now > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because now > expiry" + ); }); it("Should fail in creating the dividend - bad token", async() => { - let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because token address is 0x`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because token address is 0x" + ); }); it("Should fail in creating the dividend - amount is 0", async() => { - let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - try { - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because amount < 0`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}), + "tx -> failed because amount < 0" + ); }); it("Create new dividend of POLY tokens", async() => { @@ -447,41 +418,26 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future", async() => { - let errorThrown = false; - try { - await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because dividend index has maturity in future`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}), + "tx -> failed because dividend index has maturity in future" + ); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails not owner", async() => { - let errorThrown = false; // Increase time by 2 day await increaseTime(duration.days(2)); - try { - await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}); - } catch(error) { - console.log(` tx -> failed because msg.sender is not the owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}), + "tx -> failed because msg.sender is not the owner" + ); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index", async() => { - let errorThrown = false; - try { - await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because dividend index is greator than the dividend array length`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}), + "tx -> failed because dividend index is greator than the dividend array length" + ); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { @@ -526,51 +482,36 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); - let errorThrown = false; - try { - await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because dividend name is empty`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}), + "tx -> failed because dividend name is empty" + ); }); it("Create new dividend", async() => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - // approved in above test + // transfer approved in above test let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 1"); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry", async() => { - let errorThrown = false; await increaseTime(duration.days(12)); - try { - await I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because dividend index has passed its expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}), + "tx -> failed because dividend index has passed its expiry" + ); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoin - fails already reclaimed", async() => { - let errorThrown = false; let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); - try { - await I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); - } catch(error) { - console.log(` tx -> failed because dividend index has already reclaimed`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}), + "tx -> failed because dividend index has already been reclaimed" + ); }); it("Buy some tokens for account_investor3 (7 ETH)", async() => { @@ -600,6 +541,8 @@ contract('ERC20DividendCheckpoint', accounts => { it("Exclude account_temp using global exclusion list", async() => { await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], {from: token_owner}); + let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); + assert.equal(excluded[0], account_temp); }); it("Create another new dividend", async() => { @@ -612,18 +555,10 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("should investor 3 claims dividend - fail bad index", async() => { - let errorThrown = false; - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - try { - await I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend index is not valid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); }); it("should investor 3 claims dividend", async() => { @@ -641,15 +576,10 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("should investor 3 claims dividend - fails already claimed", async() => { - let errorThrown = false; - try { - await I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because investor already claimed the dividend`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}), + "tx -> failed because investor already claimed the dividend" + ); }); it("should issuer pushes remain", async() => { @@ -686,68 +616,48 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Create another new dividend with explicit checkpoint - fails bad allowance", async() => { - let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(2); let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); console.log(JSON.stringify(tx.logs[0].args)); console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); - try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because allowance is not provided`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), + "tx -> failed because allowance is not provided" + ); }); it("Create another new dividend with explicit - fails maturity > expiry", async() => { console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() - duration.days(10); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), {from: token_owner}); - try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because maturity > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), + "tx -> failed because maturity > expiry" + ); }); it("Create another new dividend with explicit - fails now > expiry", async() => { console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - let errorThrown = false; let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); - try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because now > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), + "tx -> failed because now > expiry" + ); }); it("Create another new dividend with explicit - fails bad checkpoint", async() => { - let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(2); - try { - tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because checkpoint id > current checkpoint`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}), + "tx -> failed because checkpoint id > current checkpoint" + ); }); it("Set withholding tax of 20% on account_temp and 10% on investor2", async() => { @@ -764,33 +674,17 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Investor 2 claims dividend, issuer pushes investor 1 - fails not owner", async() => { - let errorThrown = false; - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - try { - await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because not called by the owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}), + "tx -> failed because not called by the owner" + ); }); it("Investor 2 claims dividend, issuer pushes investor 1 - fails bad index", async() => { - let errorThrown = false; - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - try { - await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend index is not valid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); }); it("should calculate dividend before the push dividend payment", async() => { @@ -857,28 +751,25 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Issuer unable to reclaim dividend (expiry not passed)", async() => { - let errorThrown = false; - try { - await I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner}); - } catch(error) { - console.log(`Tx Failed because expiry is in the future ${0}. Test Passed Successfully`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner}), + "tx -> failed because expiry is in the future" + ); }); - it("Issuer is able to reclaim dividend after expiry", async() => { - let errorThrown = false; + it("Issuer is unable to reclaim invalid dividend", async() => { await increaseTime(11 * 24 * 60 * 60); - try { - await I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend index is not valid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + + it("Investor 3 unable to pull dividend after expiry", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), + "tx -> failed because expiry is in the past" + ); }); it("Issuer is able to reclaim dividend after expiry", async() => { @@ -889,30 +780,18 @@ contract('ERC20DividendCheckpoint', accounts => { }); - it("Issuer is able to reclaim dividend after expiry", async() => { - let errorThrown = false; - let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); - try { - await I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend are already reclaimed`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + it("Issuer is unable to reclaim already reclaimed dividend", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend are already reclaimed" + ); }); - it("Investor 3 unable to pull dividend after expiry", async() => { - let errorThrown = false; - try { - await I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}); - } catch(error) { - console.log(`Tx Failed because expiry is in the past ${0}. Test Passed Successfully`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); - + it("Investor 3 unable to pull dividend after reclaiming", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), + "tx -> failed because expiry is in the past" + ); }); it("Should give the right dividend index", async() => { From ce069842bf0e410f1467da93c998ca5fea8321cb Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 12:17:10 +0100 Subject: [PATCH 014/142] WIP --- contracts/libraries/Encoder.sol | 25 ++++++------ contracts/libraries/Util.sol | 10 ++--- contracts/libraries/VersionUtils.sol | 38 +++++++++---------- .../GeneralTransferManagerFactory.sol | 3 +- contracts/tokens/SecurityToken.sol | 16 ++++++-- 5 files changed, 51 insertions(+), 41 deletions(-) diff --git a/contracts/libraries/Encoder.sol b/contracts/libraries/Encoder.sol index edd446ef0..6e227456f 100644 --- a/contracts/libraries/Encoder.sol +++ b/contracts/libraries/Encoder.sol @@ -1,30 +1,29 @@ pragma solidity ^0.4.24; - library Encoder { - - function getKey(string _key) internal pure returns (bytes32) { + + function getKey(string _key) public pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key))); } - function getKey(string _key1, address _key2) internal pure returns (bytes32) { + function getKey(string _key1, address _key2) public pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - - function getKey(string _key1, string _key2) internal pure returns (bytes32) { + + function getKey(string _key1, string _key2) public pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - - function getKey(string _key1, uint256 _key2) internal pure returns (bytes32) { + + function getKey(string _key1, uint256 _key2) public pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - - function getKey(string _key1, bytes32 _key2) internal pure returns (bytes32) { + + function getKey(string _key1, bytes32 _key2) public pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - - function getKey(string _key1, bool _key2) internal pure returns (bytes32) { + + function getKey(string _key1, bool _key2) public pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } -} \ No newline at end of file +} diff --git a/contracts/libraries/Util.sol b/contracts/libraries/Util.sol index 4e60c9c59..10df40218 100644 --- a/contracts/libraries/Util.sol +++ b/contracts/libraries/Util.sol @@ -9,7 +9,7 @@ library Util { * @notice changes a string to upper case * @param _base string to change */ - function upper(string _base) internal pure returns (string) { + function upper(string _base) public pure returns (string) { bytes memory _baseBytes = bytes(_base); for (uint i = 0; i < _baseBytes.length; i++) { bytes1 b1 = _baseBytes[i]; @@ -26,7 +26,7 @@ library Util { * @param _source String that need to convert into bytes32 */ /// Notice - Maximum length for _source will be 32 chars otherwise returned bytes32 value will have lossy value. - function stringToBytes32(string memory _source) internal pure returns (bytes32) { + function stringToBytes32(string memory _source) public pure returns (bytes32) { return bytesToBytes32(bytes(_source), 0); } @@ -36,7 +36,7 @@ library Util { * @param _offset Offset from which to begin conversion */ /// Notice - Maximum length for _source will be 32 chars otherwise returned bytes32 value will have lossy value. - function bytesToBytes32(bytes _b, uint _offset) internal pure returns (bytes32) { + function bytesToBytes32(bytes _b, uint _offset) public pure returns (bytes32) { bytes32 result; for (uint i = 0; i < _b.length; i++) { @@ -49,7 +49,7 @@ library Util { * @notice Changes the bytes32 into string * @param _source that need to convert into string */ - function bytes32ToString(bytes32 _source) internal pure returns (string result) { + function bytes32ToString(bytes32 _source) public pure returns (string result) { bytes memory bytesString = new bytes(32); uint charCount = 0; for (uint j = 0; j < 32; j++) { @@ -71,7 +71,7 @@ library Util { * @param _data passed data * @return bytes4 sig */ - function getSig(bytes _data) internal pure returns (bytes4 sig) { + function getSig(bytes _data) public pure returns (bytes4 sig) { uint len = _data.length < 4 ? _data.length : 4; for (uint i = 0; i < len; i++) { sig = bytes4(uint(sig) + uint(_data[i]) * (2 ** (8 * (len - 1 - i)))); diff --git a/contracts/libraries/VersionUtils.sol b/contracts/libraries/VersionUtils.sol index 9b5f4fcc4..a07674647 100644 --- a/contracts/libraries/VersionUtils.sol +++ b/contracts/libraries/VersionUtils.sol @@ -5,14 +5,14 @@ pragma solidity ^0.4.24; */ library VersionUtils { - + /** * @notice This function is used to validate the version submitted * @param _current Array holds the present version of ST * @param _new Array holds the latest version of the ST - * @return bool + * @return bool */ - function isValidVersion(uint8[] _current, uint8[] _new) internal pure returns(bool) { + function isValidVersion(uint8[] _current, uint8[] _new) public pure returns(bool) { bool[] memory _temp = new bool[](_current.length); uint8 counter = 0; for (uint8 i = 0; i < _current.length; i++) { @@ -21,16 +21,16 @@ library VersionUtils { else _temp[i] = false; } - + for (i = 0; i < _current.length; i++) { if (i == 0) { if (_current[i] <= _new[i]) - if(_temp[0]) { + if(_temp[0]) { counter = counter + 3; break; } else counter++; - else + else return false; } else { if (_temp[i-1]) @@ -49,9 +49,9 @@ library VersionUtils { * @notice This function use to compare the lower bound with the latest version * @param _version1 Array holds the lower bound of the version * @param _version2 Array holds the latest version of the ST - * @return bool + * @return bool */ - function compareLowerBound(uint8[] _version1, uint8[] _version2) internal pure returns(bool) { + function compareLowerBound(uint8[] _version1, uint8[] _version2) public pure returns(bool) { require(_version1.length == _version2.length); uint counter = 0; for (uint8 j = 0; j< _version1.length; j++) { @@ -71,18 +71,18 @@ library VersionUtils { if (counter == _version1.length - 1) return true; else - return false; + return false; } else - return true; + return true; } /** * @notice This function use to compare the upper bound with the latest version * @param _version1 Array holds the upper bound of the version * @param _version2 Array holds the latest version of the ST - * @return bool + * @return bool */ - function compareUpperBound(uint8[] _version1, uint8[] _version2) internal pure returns(bool) { + function compareUpperBound(uint8[] _version1, uint8[] _version2) public pure returns(bool) { require(_version1.length == _version2.length); uint counter = 0; for (uint8 j = 0; j< _version1.length; j++) { @@ -102,19 +102,19 @@ library VersionUtils { if (counter == _version1.length - 1) return true; else - return false; + return false; } else - return true; + return true; } - + /** * @notice Use to pack the uint8[] array data into uint24 value * @param _major Major version * @param _minor Minor version * @param _patch Patch version */ - function pack(uint8 _major, uint8 _minor, uint8 _patch) internal pure returns(uint24) { + function pack(uint8 _major, uint8 _minor, uint8 _patch) public pure returns(uint24) { return (uint24(_major) << 16) | (uint24(_minor) << 8) | uint24(_patch); } @@ -122,13 +122,13 @@ library VersionUtils { * @notice Use to convert packed data into uint8 array * @param _packedVersion Packed data */ - function unpack(uint24 _packedVersion) internal pure returns (uint8[]) { + function unpack(uint24 _packedVersion) public pure returns (uint8[]) { uint8[] memory _unpackVersion = new uint8[](3); _unpackVersion[0] = uint8(_packedVersion >> 16); _unpackVersion[1] = uint8(_packedVersion >> 8); _unpackVersion[2] = uint8(_packedVersion); return _unpackVersion; } - -} \ No newline at end of file + +} diff --git a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol index 60e85f8f4..8b8dd8790 100644 --- a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol @@ -41,8 +41,9 @@ contract GeneralTransferManagerFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - uint8[] memory res = new uint8[](1); + uint8[] memory res = new uint8[](2); res[0] = 2; + res[1] = 3; return res; } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 40b032f67..d3e840261 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -68,6 +68,15 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // address whitelisted by issuer as controller address public controller; + event ModuleDataEvent( + bytes32 name, + address module, + address moduleFactory, + bool isArchived, + uint8[] moduleTypes, + uint256[] moduleIndexes, + uint256 nameIndex + ); // Struct for module data struct ModuleData { bytes32 name; @@ -269,18 +278,19 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr //Add to SecurityToken module map bytes32 moduleName = moduleFactory.getName(); uint256[] memory moduleIndexes = new uint256[](moduleTypes.length); - //TODO: Enforce uniqueness + //Enforce type uniqueness uint256 i; uint256 j; for (i = 0; i < moduleTypes.length; i++) { - for (j = i; j < moduleTypes.length; j++) { + for (j = 0; j < i; j++) { require(moduleTypes[i] != moduleTypes[j], "Bad types"); } } for (i = 0; i < moduleTypes.length; i++) { moduleIndexes[i] = modules[moduleTypes[i]].length; } - modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); + emit ModuleDataEvent(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); + /* modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); */ for (i = 0; i < moduleTypes.length; i++) { modules[moduleTypes[i]].push(module); } From f91dd2728a7575ea02c3e325ee73db842c4910d6 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Wed, 3 Oct 2018 16:56:05 +0530 Subject: [PATCH 015/142] DividendCheckpoint test cases added --- test/e_erc20_dividends.js | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index e45808916..5c35458d3 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -539,12 +539,37 @@ contract('ERC20DividendCheckpoint', accounts => { ); }); + it("Should allow to exclude same number of address as EXCLUDED_ADDRESS_LIMIT", async() => { + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber() - 1; + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}); + let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); + assert.equal(excluded[0], account_temp); + }); + it("Exclude account_temp using global exclusion list", async() => { await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], {from: token_owner}); let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); assert.equal(excluded[0], account_temp); }); + it("Should not allow to exclude more address than EXCLUDED_ADDRESS_LIMIT", async() => { + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await catchRevert( + I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}), + "tx -> failed because exclude address more than limit" + ); + }); + it("Create another new dividend", async() => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); @@ -664,6 +689,24 @@ contract('ERC20DividendCheckpoint', accounts => { await I_ERC20DividendCheckpoint.setWithholding([account_temp, account_investor2], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}); }); + it("Should not allow mismatching input lengths", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}), + "tx -> failed because mismatching input lengths" + ); + }); + + it("Should not allow withholding greater than limit", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**26)], {from: token_owner}), + "tx -> failed because withholding greater than limit" + ); + await catchRevert( + I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20*10**26), {from: token_owner}), + "" + ); + }); + it("Create another new dividend with explicit checkpoint and exclusion", async() => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); @@ -673,6 +716,13 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 3"); }); + it("Should not allow excluded to pull Dividend Payment", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor1, gasPrice: 0}), + "tx -> failed because msg.sender is excluded" + ); + }); + it("Investor 2 claims dividend, issuer pushes investor 1 - fails not owner", async() => { await catchRevert( I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}), @@ -687,6 +737,13 @@ contract('ERC20DividendCheckpoint', accounts => { ); }); + it("should not calculate dividend for invalid index", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1), + "tx -> failed because dividend index is not valid" + ); + }); + it("should calculate dividend before the push dividend payment", async() => { let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); @@ -818,6 +875,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("should get the exact details of the factory", async() => { assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_ERC20DividendCheckpointFactory.getVersion.call(), "1.0.0"); assert.equal(web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()) .replace(/\u0000/g, ''), "ERC20DividendCheckpoint", From 7b09033870b2bd404ee592765d59483f62ee6a6b Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Wed, 3 Oct 2018 17:03:33 +0530 Subject: [PATCH 016/142] ERC20 Dividends test cases added --- test/e_erc20_dividends.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 5c35458d3..e9453006a 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -707,11 +707,28 @@ contract('ERC20DividendCheckpoint', accounts => { ); }); - it("Create another new dividend with explicit checkpoint and exclusion", async() => { + it("Should not create dividend with more exclusions than limit", async() => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, addresses, dividendName, {from: token_owner}), + "tx -> failed because too many address excluded" + ); + }); + + it("Create another new dividend with explicit checkpoint and exclusion", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + //token transfer approved in above test let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, [account_investor1], dividendName, {from: token_owner}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 3"); }); @@ -800,6 +817,13 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal(dividendAmount2[0].toNumber(), 0); }); + it("Should not allow reclaiming withholding tax with incorrect index", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + it("Issuer reclaims withholding tax", async() => { let issuerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); await I_ERC20DividendCheckpoint.withdrawWithholding(3, {from: token_owner, gasPrice: 0}); From 3104215126cfce6b0e6c85cc289d989c31659892 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Wed, 3 Oct 2018 17:15:28 +0530 Subject: [PATCH 017/142] ether dividend test cases added --- test/f_ether_dividends.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index dec4be72f..aff9c6f49 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -484,6 +485,13 @@ contract('EtherDividendCheckpoint', accounts => { assert.equal((await I_EtherDividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); }); + it("Should not allow reclaiming withholding tax with incorrect index", async() => { + await catchRevert( + I_EtherDividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + it("Issuer reclaims withholding tax", async() => { let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); @@ -729,11 +737,27 @@ contract('EtherDividendCheckpoint', accounts => { assert.ok(errorThrown, message); }); + it("Should not create dividend with more exclusions than limit", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_SecurityToken.createCheckpoint({from: token_owner}); + let limit = await I_EtherDividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, addresses, dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}), + "tx -> failed because too many address excluded" + ); + }); + it("Create another new dividend with explicit checkpoint and excluding account_investor1", async() => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, [account_investor1], dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}); + //checkpoint created in above test + let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, [account_investor1], dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 4"); }); @@ -959,6 +983,7 @@ contract('EtherDividendCheckpoint', accounts => { it("should get the exact details of the factory", async() => { assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); assert.equal(await I_EtherDividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_EtherDividendCheckpointFactory.getVersion.call(), "1.0.0"); assert.equal(web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()) .replace(/\u0000/g, ''), "EtherDividendCheckpoint", From ceed74e2bb883ba50ea1ad7179317a151600532f Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 13:43:34 +0100 Subject: [PATCH 018/142] WIP --- contracts/libraries/Encoder.sol | 12 +- migrations/2_deploy_contracts.js | 458 +++++++++++++++++-------------- 2 files changed, 257 insertions(+), 213 deletions(-) diff --git a/contracts/libraries/Encoder.sol b/contracts/libraries/Encoder.sol index 6e227456f..27d9a4ddf 100644 --- a/contracts/libraries/Encoder.sol +++ b/contracts/libraries/Encoder.sol @@ -2,27 +2,27 @@ pragma solidity ^0.4.24; library Encoder { - function getKey(string _key) public pure returns (bytes32) { + function getKey(string _key) internal pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key))); } - function getKey(string _key1, address _key2) public pure returns (bytes32) { + function getKey(string _key1, address _key2) internal pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - function getKey(string _key1, string _key2) public pure returns (bytes32) { + function getKey(string _key1, string _key2) internal pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - function getKey(string _key1, uint256 _key2) public pure returns (bytes32) { + function getKey(string _key1, uint256 _key2) internal pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - function getKey(string _key1, bytes32 _key2) public pure returns (bytes32) { + function getKey(string _key1, bytes32 _key2) internal pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } - function getKey(string _key1, bool _key2) public pure returns (bytes32) { + function getKey(string _key1, bool _key2) internal pure returns (bytes32) { return bytes32(keccak256(abi.encodePacked(_key1, _key2))); } diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 97124b804..2a8804d49 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -17,6 +17,9 @@ 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') +const VersionUtils = artifacts.require('./VersionUtils.sol'); +const Util = artifacts.require('./Util.sol'); + let BigNumber = require('bignumber.js'); const cappedSTOSetupCost = new BigNumber(20000).times(new BigNumber(10).pow(18)); // 20K POLY fee const usdTieredSTOSetupCost = new BigNumber(100000).times(new BigNumber(10).pow(18)); // 100K POLY fee @@ -30,8 +33,9 @@ const Web3 = require('web3') module.exports = function (deployer, network, accounts) { // Ethereum account address hold by the Polymath (Act as the main account which have ownable permissions) - let PolymathAccount - let moduleRegistry + let PolymathAccount; + let moduleRegistry; + let polymathRegistry; let web3 if (network === 'development') { web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')) @@ -52,6 +56,7 @@ module.exports = function (deployer, network, accounts) { ETHOracle = mockedOracle.address; }); }); + } else if (network === 'kovan') { web3 = new Web3(new Web3.providers.HttpProvider('https://kovan.infura.io/g5xfoQ0jFSE9S5LwM1Ei')) PolymathAccount = accounts[0] @@ -101,220 +106,259 @@ module.exports = function (deployer, network, accounts) { },{ type: 'address', name: '_owner' - } -] -}; + }] + }; -const functionSignatureProxyMR = { - name: 'initialize', - type: 'function', - inputs: [{ - type:'address', - name: '_polymathRegistry' - },{ - type: 'address', - name: '_owner' - } -] -}; + const functionSignatureProxyMR = { + name: 'initialize', + type: 'function', + inputs: [{ + type:'address', + name: '_polymathRegistry' + },{ + type: 'address', + name: '_owner' + }] + }; // POLYMATH NETWORK Configuration :: DO THIS ONLY ONCE // A) Deploy the PolymathRegistry contract return deployer.deploy(PolymathRegistry, {from: PolymathAccount}).then(() => { - return PolymathRegistry.deployed().then((polymathRegistry) => { - - return polymathRegistry.changeAddress("PolyToken", PolyToken, {from: PolymathAccount}) - .then(() => { - // A) Deploy the ModuleRegistry Contract (It contains the list of verified ModuleFactory) - return deployer.deploy(ModuleRegistry, {from: PolymathAccount}); - }).then(() => { - return deployer.deploy(ModuleRegistryProxy, {from: PolymathAccount}); - }).then(() => { - let bytesProxyMR = web3.eth.abi.encodeFunctionCall(functionSignatureProxyMR, [polymathRegistry.address, PolymathAccount]); - ModuleRegistryProxy.at(ModuleRegistryProxy.address).upgradeToAndCall("1.0.0", ModuleRegistry.address, bytesProxyMR, {from: PolymathAccount}); - }).then(() => { - moduleRegistry = ModuleRegistry.at(ModuleRegistryProxy.address); - // Add module registry to polymath registry - return polymathRegistry.changeAddress("ModuleRegistry", ModuleRegistryProxy.address, {from: PolymathAccount}); - }).then(() => { - // B) Deploy the GeneralTransferManagerFactory Contract (Factory used to generate the GeneralTransferManager contract and this - // manager attach with the securityToken contract at the time of deployment) - return deployer.deploy(GeneralTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); - }).then(() => { - // C) Deploy the GeneralPermissionManagerFactory Contract (Factory used to generate the GeneralPermissionManager contract and - // this manager attach with the securityToken contract at the time of deployment) - return deployer.deploy(GeneralPermissionManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); - }).then(() => { - // D) Deploy the CountTransferManagerFactory Contract (Factory used to generate the CountTransferManager contract use - // to track the counts of the investors of the security token) - return deployer.deploy(CountTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); - }).then(() => { - // D) Deploy the PercentageTransferManagerFactory Contract (Factory used to generate the PercentageTransferManager contract use - // to track the percentage of investment the investors could do for a particular security token) - return deployer.deploy(PercentageTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); - }).then(() => { - // D) Deploy the EtherDividendCheckpointFactory Contract (Factory used to generate the EtherDividendCheckpoint contract use - // to provide the functionality of the dividend in terms of ETH) - return deployer.deploy(EtherDividendCheckpointFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); - }).then(() => { - // D) Deploy the ERC20DividendCheckpointFactory Contract (Factory used to generate the ERC20DividendCheckpoint contract use - // to provide the functionality of the dividend in terms of ERC20 token) - return deployer.deploy(ERC20DividendCheckpointFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); - }).then(() => { - // D) Deploy the ManualApprovalTransferManagerFactory Contract (Factory used to generate the ManualApprovalTransferManager contract use - // to manual approve the transfer that will overcome the other transfer restrictions) - return deployer.deploy(ManualApprovalTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); - }).then(() => { - // H) Deploy the STVersionProxy001 Contract which contains the logic of deployment of securityToken. - return deployer.deploy(STFactory, GeneralTransferManagerFactory.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(() => { - // J) Deploy the SecurityTokenRegistry contract (Used to hold the deployed secuirtyToken details. It also act as the interface to deploy the SecurityToken) - return deployer.deploy(SecurityTokenRegistry, {from: PolymathAccount}) - }).then(()=> { - return deployer.deploy(SecurityTokenRegistryProxy, {from: PolymathAccount}); - }).then(() => { - let bytesProxy = web3.eth.abi.encodeFunctionCall(functionSignatureProxy, [PolymathRegistry.address, STFactory.address, initRegFee, initRegFee, PolyToken, PolymathAccount]); - SecurityTokenRegistryProxy.at(SecurityTokenRegistryProxy.address).upgradeToAndCall("1.0.0", SecurityTokenRegistry.address, bytesProxy, {from: PolymathAccount}); - }).then(() => { - // Assign the address into the SecurityTokenRegistry key - return polymathRegistry.changeAddress("SecurityTokenRegistry", SecurityTokenRegistryProxy.address, {from: PolymathAccount}); - }).then(() => { - // Update all addresses into the registry contract by calling the function updateFromregistry - return moduleRegistry.updateFromRegistry({from: PolymathAccount}); - }).then(() => { - // D) Register the PercentageTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the PercentageTransferManager contract. - return moduleRegistry.registerModule(PercentageTransferManagerFactory.address, {from: PolymathAccount}); - }).then(() => { - // D) Register the CountTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the CountTransferManager contract. - return moduleRegistry.registerModule(CountTransferManagerFactory.address, {from: PolymathAccount}); - }).then(() => { - // D) Register the GeneralTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the GeneralTransferManager contract. - return moduleRegistry.registerModule(GeneralTransferManagerFactory.address, {from: PolymathAccount}); - }).then(() => { - // E) Register the GeneralPermissionManagerFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the GeneralPermissionManager contract. - return moduleRegistry.registerModule(GeneralPermissionManagerFactory.address, {from: PolymathAccount}); - }).then(() => { - // E) Register the GeneralPermissionManagerFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the GeneralPermissionManager contract. - return moduleRegistry.registerModule(EtherDividendCheckpointFactory.address, {from: PolymathAccount}); - }).then(() => { - // D) Register the ManualApprovalTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the ManualApprovalTransferManager contract. - return moduleRegistry.registerModule(ManualApprovalTransferManagerFactory.address, {from: PolymathAccount}); - }).then(() => { - // E) Register the ERC20DividendCheckpointFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the ERC20DividendCheckpoint contract. - return moduleRegistry.registerModule(ERC20DividendCheckpointFactory.address, {from: PolymathAccount}); - }).then(() => { - // F) Once the GeneralTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(GeneralTransferManagerFactory.address, true, {from: PolymathAccount}); - }).then(() => { - // G) Once the CountTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(CountTransferManagerFactory.address, true, {from: PolymathAccount}); - }).then(() => { - // G) Once the PercentageTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(PercentageTransferManagerFactory.address, true, {from: PolymathAccount}); - }).then(() => { - // G) Once the GeneralPermissionManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(GeneralPermissionManagerFactory.address, true, {from: PolymathAccount}) - }).then(() => { - // G) Once the EtherDividendCheckpointFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(EtherDividendCheckpointFactory.address, true, {from: PolymathAccount}); - }).then(() => { - // G) Once the ERC20DividendCheckpointFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(ERC20DividendCheckpointFactory.address, true, {from: PolymathAccount}); - }).then(() => { - // G) Once the ManualApprovalTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(ManualApprovalTransferManagerFactory.address, true, {from: PolymathAccount}); - }).then(() => { - // M) Deploy the CappedSTOFactory (Use to generate the CappedSTO contract which will used to collect the funds ). - return deployer.deploy(CappedSTOFactory, PolyToken, cappedSTOSetupCost, 0, 0, {from: PolymathAccount}) - }).then(() => { - // N) Register the CappedSTOFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the CappedSTOFactory contract. - return moduleRegistry.registerModule(CappedSTOFactory.address, {from: PolymathAccount}) - }).then(()=>{ - // G) Once the CappedSTOFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(CappedSTOFactory.address, true, {from: PolymathAccount}) - }).then(() => { - // Deploy the proxy factory - return deployer.deploy(USDTieredSTOProxyFactory, {from: PolymathAccount}); - }).then(() => { - // H) Deploy the USDTieredSTOFactory (Use to generate the USDTieredSTOFactory contract which will used to collect the funds ). - return deployer.deploy(USDTieredSTOFactory, PolyToken, usdTieredSTOSetupCost, 0, 0, USDTieredSTOProxyFactory.address, {from: PolymathAccount}) - }).then(() => { - // I) Register the USDTieredSTOFactory in the ModuleRegistry to make the factory available at the protocol level. - // So any securityToken can use that factory to generate the USDTieredSTOFactory contract. - return moduleRegistry.registerModule(USDTieredSTOFactory.address, {from: PolymathAccount}) - }).then(()=>{ - // J) Once the USDTieredSTOFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken - // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. - // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(USDTieredSTOFactory.address, true, {from: PolymathAccount}) - }).then(() => { - return polymathRegistry.changeAddress("PolyUsdOracle", POLYOracle, {from: PolymathAccount}); - }).then(() => { - return polymathRegistry.changeAddress("EthUsdOracle", ETHOracle, {from: PolymathAccount}); - }).then(() => { - console.log('\n'); - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} + return PolymathRegistry.deployed(); + }).then((_polymathRegistry) => { + polymathRegistry = _polymathRegistry; + return polymathRegistry.changeAddress("PolyToken", PolyToken, {from: PolymathAccount}); + }).then(() => { + // Deploy libraries + return deployer.deploy(VersionUtils, {from: PolymathAccount}); + }).then(() => { + return deployer.deploy(Util, {from: PolymathAccount}); + }).then(() => { + // Link libraries + return deployer.link(VersionUtils, ModuleRegistry); + }).then(() => { + return deployer.link(VersionUtils, SecurityTokenRegistry); + }).then(() => { + return deployer.link(VersionUtils, GeneralTransferManagerFactory); + }).then(() => { + return deployer.link(VersionUtils, GeneralPermissionManagerFactory); + }).then(() => { + return deployer.link(VersionUtils, PercentageTransferManagerFactory); + }).then(() => { + return deployer.link(VersionUtils, USDTieredSTOProxyFactory); + }).then(() => { + return deployer.link(VersionUtils, CountTransferManagerFactory); + }).then(() => { + return deployer.link(VersionUtils, EtherDividendCheckpointFactory); + }).then(() => { + return deployer.link(VersionUtils, ERC20DividendCheckpointFactory); + }).then(() => { + return deployer.link(VersionUtils, ManualApprovalTransferManagerFactory); + }).then(() => { + return deployer.link(VersionUtils, CappedSTOFactory); + }).then(() => { + return deployer.link(VersionUtils, USDTieredSTOFactory); + }).then(() => { + return deployer.link(Util, CappedSTOFactory); + }).then(() => { + return deployer.link(Util, USDTieredSTOFactory); + }).then(() => { + return deployer.link(Util, CountTransferManagerFactory); + }).then(() => { + return deployer.link(Util, PercentageTransferManagerFactory); + }).then(() => { + return deployer.link(Util, SecurityTokenRegistry); + }).then(() => { + return deployer.link(Util, STFactory); + }).then(() => { + // A) Deploy the ModuleRegistry Contract (It contains the list of verified ModuleFactory) + return deployer.deploy(ModuleRegistry, {from: PolymathAccount}); + }).then(() => { + return deployer.deploy(ModuleRegistryProxy, {from: PolymathAccount}); + }).then(() => { + let bytesProxyMR = web3.eth.abi.encodeFunctionCall(functionSignatureProxyMR, [polymathRegistry.address, PolymathAccount]); + ModuleRegistryProxy.at(ModuleRegistryProxy.address).upgradeToAndCall("1.0.0", ModuleRegistry.address, bytesProxyMR, {from: PolymathAccount}); + }).then(() => { + moduleRegistry = ModuleRegistry.at(ModuleRegistryProxy.address); + // Add module registry to polymath registry + return polymathRegistry.changeAddress("ModuleRegistry", ModuleRegistryProxy.address, {from: PolymathAccount}); + }).then(() => { + // B) Deploy the GeneralTransferManagerFactory Contract (Factory used to generate the GeneralTransferManager contract and this + // manager attach with the securityToken contract at the time of deployment) + return deployer.deploy(GeneralTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); + }).then(() => { + // C) Deploy the GeneralPermissionManagerFactory Contract (Factory used to generate the GeneralPermissionManager contract and + // this manager attach with the securityToken contract at the time of deployment) + return deployer.deploy(GeneralPermissionManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); + }).then(() => { + // D) Deploy the CountTransferManagerFactory Contract (Factory used to generate the CountTransferManager contract use + // to track the counts of the investors of the security token) + return deployer.deploy(CountTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); + }).then(() => { + // D) Deploy the PercentageTransferManagerFactory Contract (Factory used to generate the PercentageTransferManager contract use + // to track the percentage of investment the investors could do for a particular security token) + return deployer.deploy(PercentageTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); + }).then(() => { + // D) Deploy the EtherDividendCheckpointFactory Contract (Factory used to generate the EtherDividendCheckpoint contract use + // to provide the functionality of the dividend in terms of ETH) + return deployer.deploy(EtherDividendCheckpointFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); + }).then(() => { + // D) Deploy the ERC20DividendCheckpointFactory Contract (Factory used to generate the ERC20DividendCheckpoint contract use + // to provide the functionality of the dividend in terms of ERC20 token) + return deployer.deploy(ERC20DividendCheckpointFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); + }).then(() => { + // D) Deploy the ManualApprovalTransferManagerFactory Contract (Factory used to generate the ManualApprovalTransferManager contract use + // to manual approve the transfer that will overcome the other transfer restrictions) + return deployer.deploy(ManualApprovalTransferManagerFactory, PolyToken, 0, 0, 0, {from: PolymathAccount}); + }).then(() => { + // H) Deploy the STVersionProxy001 Contract which contains the logic of deployment of securityToken. + return deployer.deploy(STFactory, GeneralTransferManagerFactory.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(() => { + // J) Deploy the SecurityTokenRegistry contract (Used to hold the deployed secuirtyToken details. It also act as the interface to deploy the SecurityToken) + return deployer.deploy(SecurityTokenRegistry, {from: PolymathAccount}) + }).then(()=> { + return deployer.deploy(SecurityTokenRegistryProxy, {from: PolymathAccount}); + }).then(() => { + let bytesProxy = web3.eth.abi.encodeFunctionCall(functionSignatureProxy, [PolymathRegistry.address, STFactory.address, initRegFee, initRegFee, PolyToken, PolymathAccount]); + SecurityTokenRegistryProxy.at(SecurityTokenRegistryProxy.address).upgradeToAndCall("1.0.0", SecurityTokenRegistry.address, bytesProxy, {from: PolymathAccount}); + }).then(() => { + // Assign the address into the SecurityTokenRegistry key + return polymathRegistry.changeAddress("SecurityTokenRegistry", SecurityTokenRegistryProxy.address, {from: PolymathAccount}); + }).then(() => { + // Update all addresses into the registry contract by calling the function updateFromregistry + return moduleRegistry.updateFromRegistry({from: PolymathAccount}); + }).then(() => { + // D) Register the PercentageTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the PercentageTransferManager contract. + return moduleRegistry.registerModule(PercentageTransferManagerFactory.address, {from: PolymathAccount}); + }).then(() => { + // D) Register the CountTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the CountTransferManager contract. + return moduleRegistry.registerModule(CountTransferManagerFactory.address, {from: PolymathAccount}); + }).then(() => { + // D) Register the GeneralTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the GeneralTransferManager contract. + return moduleRegistry.registerModule(GeneralTransferManagerFactory.address, {from: PolymathAccount}); + }).then(() => { + // E) Register the GeneralPermissionManagerFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the GeneralPermissionManager contract. + return moduleRegistry.registerModule(GeneralPermissionManagerFactory.address, {from: PolymathAccount}); + }).then(() => { + // E) Register the GeneralPermissionManagerFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the GeneralPermissionManager contract. + return moduleRegistry.registerModule(EtherDividendCheckpointFactory.address, {from: PolymathAccount}); + }).then(() => { + // D) Register the ManualApprovalTransferManagerFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the ManualApprovalTransferManager contract. + return moduleRegistry.registerModule(ManualApprovalTransferManagerFactory.address, {from: PolymathAccount}); + }).then(() => { + // E) Register the ERC20DividendCheckpointFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the ERC20DividendCheckpoint contract. + return moduleRegistry.registerModule(ERC20DividendCheckpointFactory.address, {from: PolymathAccount}); + }).then(() => { + // F) Once the GeneralTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(GeneralTransferManagerFactory.address, true, {from: PolymathAccount}); + }).then(() => { + // G) Once the CountTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(CountTransferManagerFactory.address, true, {from: PolymathAccount}); + }).then(() => { + // G) Once the PercentageTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(PercentageTransferManagerFactory.address, true, {from: PolymathAccount}); + }).then(() => { + // G) Once the GeneralPermissionManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(GeneralPermissionManagerFactory.address, true, {from: PolymathAccount}) + }).then(() => { + // G) Once the EtherDividendCheckpointFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(EtherDividendCheckpointFactory.address, true, {from: PolymathAccount}); + }).then(() => { + // G) Once the ERC20DividendCheckpointFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(ERC20DividendCheckpointFactory.address, true, {from: PolymathAccount}); + }).then(() => { + // G) Once the ManualApprovalTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(ManualApprovalTransferManagerFactory.address, true, {from: PolymathAccount}); + }).then(() => { + // M) Deploy the CappedSTOFactory (Use to generate the CappedSTO contract which will used to collect the funds ). + return deployer.deploy(CappedSTOFactory, PolyToken, cappedSTOSetupCost, 0, 0, {from: PolymathAccount}) + }).then(() => { + // N) Register the CappedSTOFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the CappedSTOFactory contract. + return moduleRegistry.registerModule(CappedSTOFactory.address, {from: PolymathAccount}) + }).then(()=>{ + // G) Once the CappedSTOFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(CappedSTOFactory.address, true, {from: PolymathAccount}) + }).then(() => { + // Deploy the proxy factory + return deployer.deploy(USDTieredSTOProxyFactory, {from: PolymathAccount}); + }).then(() => { + // H) Deploy the USDTieredSTOFactory (Use to generate the USDTieredSTOFactory contract which will used to collect the funds ). + return deployer.deploy(USDTieredSTOFactory, PolyToken, usdTieredSTOSetupCost, 0, 0, USDTieredSTOProxyFactory.address, {from: PolymathAccount}) + }).then(() => { + // I) Register the USDTieredSTOFactory in the ModuleRegistry to make the factory available at the protocol level. + // So any securityToken can use that factory to generate the USDTieredSTOFactory contract. + return moduleRegistry.registerModule(USDTieredSTOFactory.address, {from: PolymathAccount}) + }).then(()=>{ + // J) Once the USDTieredSTOFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken + // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. + // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. + return moduleRegistry.verifyModule(USDTieredSTOFactory.address, true, {from: PolymathAccount}) + }).then(() => { + return polymathRegistry.changeAddress("PolyUsdOracle", POLYOracle, {from: PolymathAccount}); + }).then(() => { + return polymathRegistry.changeAddress("EthUsdOracle", ETHOracle, {from: PolymathAccount}); + }).then(() => { + console.log('\n'); + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + ModuleRegistryProxy: ${ModuleRegistryProxy.address} + FeatureRegistry: ${FeatureRegistry.address} - ETHOracle: ${ETHOracle} - POLYOracle: ${POLYOracle} + 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} - USDTieredSTOProxyFactory: ${USDTieredSTOProxyFactory.address} + CappedSTOFactory: ${CappedSTOFactory.address} + USDTieredSTOFactory: ${USDTieredSTOFactory.address} + USDTieredSTOProxyFactory: ${USDTieredSTOProxyFactory.address} - CountTransferManagerFactory: ${CountTransferManagerFactory.address} - PercentageTransferManagerFactory: ${PercentageTransferManagerFactory.address} - ManualApprovalTransferManagerFactory: - ${ManualApprovalTransferManagerFactory.address} + CountTransferManagerFactory: ${CountTransferManagerFactory.address} + PercentageTransferManagerFactory: ${PercentageTransferManagerFactory.address} + ManualApprovalTransferManagerFactory: + ${ManualApprovalTransferManagerFactory.address} - EtherDividendCheckpointFactory: ${EtherDividendCheckpointFactory.address} - ERC20DividendCheckpointFactory: ${ERC20DividendCheckpointFactory.address} - ----------------------------------------------------------------------------- - `); - console.log('\n'); - // -------- END OF POLYMATH NETWORK Configuration -------// - }); + EtherDividendCheckpointFactory: ${EtherDividendCheckpointFactory.address} + ERC20DividendCheckpointFactory: ${ERC20DividendCheckpointFactory.address} + ----------------------------------------------------------------------------- + `); + console.log('\n'); + // -------- END OF POLYMATH NETWORK Configuration -------// }); -}); } From e7caf0d1597adc1343b18836b27814dd0ace416d Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 15:18:13 +0100 Subject: [PATCH 019/142] Go back to in-lined internals --- contracts/libraries/Util.sol | 10 ++-- contracts/libraries/VersionUtils.sol | 10 ++-- migrations/2_deploy_contracts.js | 84 ++++++++++++++-------------- 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/contracts/libraries/Util.sol b/contracts/libraries/Util.sol index 10df40218..4e60c9c59 100644 --- a/contracts/libraries/Util.sol +++ b/contracts/libraries/Util.sol @@ -9,7 +9,7 @@ library Util { * @notice changes a string to upper case * @param _base string to change */ - function upper(string _base) public pure returns (string) { + function upper(string _base) internal pure returns (string) { bytes memory _baseBytes = bytes(_base); for (uint i = 0; i < _baseBytes.length; i++) { bytes1 b1 = _baseBytes[i]; @@ -26,7 +26,7 @@ library Util { * @param _source String that need to convert into bytes32 */ /// Notice - Maximum length for _source will be 32 chars otherwise returned bytes32 value will have lossy value. - function stringToBytes32(string memory _source) public pure returns (bytes32) { + function stringToBytes32(string memory _source) internal pure returns (bytes32) { return bytesToBytes32(bytes(_source), 0); } @@ -36,7 +36,7 @@ library Util { * @param _offset Offset from which to begin conversion */ /// Notice - Maximum length for _source will be 32 chars otherwise returned bytes32 value will have lossy value. - function bytesToBytes32(bytes _b, uint _offset) public pure returns (bytes32) { + function bytesToBytes32(bytes _b, uint _offset) internal pure returns (bytes32) { bytes32 result; for (uint i = 0; i < _b.length; i++) { @@ -49,7 +49,7 @@ library Util { * @notice Changes the bytes32 into string * @param _source that need to convert into string */ - function bytes32ToString(bytes32 _source) public pure returns (string result) { + function bytes32ToString(bytes32 _source) internal pure returns (string result) { bytes memory bytesString = new bytes(32); uint charCount = 0; for (uint j = 0; j < 32; j++) { @@ -71,7 +71,7 @@ library Util { * @param _data passed data * @return bytes4 sig */ - function getSig(bytes _data) public pure returns (bytes4 sig) { + function getSig(bytes _data) internal pure returns (bytes4 sig) { uint len = _data.length < 4 ? _data.length : 4; for (uint i = 0; i < len; i++) { sig = bytes4(uint(sig) + uint(_data[i]) * (2 ** (8 * (len - 1 - i)))); diff --git a/contracts/libraries/VersionUtils.sol b/contracts/libraries/VersionUtils.sol index a07674647..41689713d 100644 --- a/contracts/libraries/VersionUtils.sol +++ b/contracts/libraries/VersionUtils.sol @@ -12,7 +12,7 @@ library VersionUtils { * @param _new Array holds the latest version of the ST * @return bool */ - function isValidVersion(uint8[] _current, uint8[] _new) public pure returns(bool) { + function isValidVersion(uint8[] _current, uint8[] _new) internal pure returns(bool) { bool[] memory _temp = new bool[](_current.length); uint8 counter = 0; for (uint8 i = 0; i < _current.length; i++) { @@ -51,7 +51,7 @@ library VersionUtils { * @param _version2 Array holds the latest version of the ST * @return bool */ - function compareLowerBound(uint8[] _version1, uint8[] _version2) public pure returns(bool) { + function compareLowerBound(uint8[] _version1, uint8[] _version2) internal pure returns(bool) { require(_version1.length == _version2.length); uint counter = 0; for (uint8 j = 0; j< _version1.length; j++) { @@ -82,7 +82,7 @@ library VersionUtils { * @param _version2 Array holds the latest version of the ST * @return bool */ - function compareUpperBound(uint8[] _version1, uint8[] _version2) public pure returns(bool) { + function compareUpperBound(uint8[] _version1, uint8[] _version2) internal pure returns(bool) { require(_version1.length == _version2.length); uint counter = 0; for (uint8 j = 0; j< _version1.length; j++) { @@ -114,7 +114,7 @@ library VersionUtils { * @param _minor Minor version * @param _patch Patch version */ - function pack(uint8 _major, uint8 _minor, uint8 _patch) public pure returns(uint24) { + function pack(uint8 _major, uint8 _minor, uint8 _patch) internal pure returns(uint24) { return (uint24(_major) << 16) | (uint24(_minor) << 8) | uint24(_patch); } @@ -122,7 +122,7 @@ library VersionUtils { * @notice Use to convert packed data into uint8 array * @param _packedVersion Packed data */ - function unpack(uint24 _packedVersion) public pure returns (uint8[]) { + function unpack(uint24 _packedVersion) internal pure returns (uint8[]) { uint8[] memory _unpackVersion = new uint8[](3); _unpackVersion[0] = uint8(_packedVersion >> 16); _unpackVersion[1] = uint8(_packedVersion >> 8); diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 2a8804d49..4a78f3ec2 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -128,48 +128,48 @@ module.exports = function (deployer, network, accounts) { }).then((_polymathRegistry) => { polymathRegistry = _polymathRegistry; return polymathRegistry.changeAddress("PolyToken", PolyToken, {from: PolymathAccount}); - }).then(() => { - // Deploy libraries - return deployer.deploy(VersionUtils, {from: PolymathAccount}); - }).then(() => { - return deployer.deploy(Util, {from: PolymathAccount}); - }).then(() => { - // Link libraries - return deployer.link(VersionUtils, ModuleRegistry); - }).then(() => { - return deployer.link(VersionUtils, SecurityTokenRegistry); - }).then(() => { - return deployer.link(VersionUtils, GeneralTransferManagerFactory); - }).then(() => { - return deployer.link(VersionUtils, GeneralPermissionManagerFactory); - }).then(() => { - return deployer.link(VersionUtils, PercentageTransferManagerFactory); - }).then(() => { - return deployer.link(VersionUtils, USDTieredSTOProxyFactory); - }).then(() => { - return deployer.link(VersionUtils, CountTransferManagerFactory); - }).then(() => { - return deployer.link(VersionUtils, EtherDividendCheckpointFactory); - }).then(() => { - return deployer.link(VersionUtils, ERC20DividendCheckpointFactory); - }).then(() => { - return deployer.link(VersionUtils, ManualApprovalTransferManagerFactory); - }).then(() => { - return deployer.link(VersionUtils, CappedSTOFactory); - }).then(() => { - return deployer.link(VersionUtils, USDTieredSTOFactory); - }).then(() => { - return deployer.link(Util, CappedSTOFactory); - }).then(() => { - return deployer.link(Util, USDTieredSTOFactory); - }).then(() => { - return deployer.link(Util, CountTransferManagerFactory); - }).then(() => { - return deployer.link(Util, PercentageTransferManagerFactory); - }).then(() => { - return deployer.link(Util, SecurityTokenRegistry); - }).then(() => { - return deployer.link(Util, STFactory); + // }).then(() => { + // // Deploy libraries + // return deployer.deploy(VersionUtils, {from: PolymathAccount}); + // }).then(() => { + // return deployer.deploy(Util, {from: PolymathAccount}); + // }).then(() => { + // // Link libraries + // return deployer.link(VersionUtils, ModuleRegistry); + // }).then(() => { + // return deployer.link(VersionUtils, SecurityTokenRegistry); + // }).then(() => { + // return deployer.link(VersionUtils, GeneralTransferManagerFactory); + // }).then(() => { + // return deployer.link(VersionUtils, GeneralPermissionManagerFactory); + // }).then(() => { + // return deployer.link(VersionUtils, PercentageTransferManagerFactory); + // }).then(() => { + // return deployer.link(VersionUtils, USDTieredSTOProxyFactory); + // }).then(() => { + // return deployer.link(VersionUtils, CountTransferManagerFactory); + // }).then(() => { + // return deployer.link(VersionUtils, EtherDividendCheckpointFactory); + // }).then(() => { + // return deployer.link(VersionUtils, ERC20DividendCheckpointFactory); + // }).then(() => { + // return deployer.link(VersionUtils, ManualApprovalTransferManagerFactory); + // }).then(() => { + // return deployer.link(VersionUtils, CappedSTOFactory); + // }).then(() => { + // return deployer.link(VersionUtils, USDTieredSTOFactory); + // }).then(() => { + // return deployer.link(Util, CappedSTOFactory); + // }).then(() => { + // return deployer.link(Util, USDTieredSTOFactory); + // }).then(() => { + // return deployer.link(Util, CountTransferManagerFactory); + // }).then(() => { + // return deployer.link(Util, PercentageTransferManagerFactory); + // }).then(() => { + // return deployer.link(Util, SecurityTokenRegistry); + // }).then(() => { + // return deployer.link(Util, STFactory); }).then(() => { // A) Deploy the ModuleRegistry Contract (It contains the list of verified ModuleFactory) return deployer.deploy(ModuleRegistry, {from: PolymathAccount}); From 0a00f95bfd6a384e915d19aa09b9be8ed146b4d2 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 15:21:47 +0100 Subject: [PATCH 020/142] Remove merge cruft --- contracts/SecurityTokenRegistry.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index e70c19be0..8f2229b59 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -278,11 +278,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { return true; } -<<<<<<< HEAD function _tickerStatus(string _ticker) internal view returns(bool) { -======= - function _tickerStatus(string _ticker) internal returns(bool) { ->>>>>>> development-1.5.0 return getBool(Encoder.getKey("registeredTickers_status", _ticker)); } From 85a8ba6969c151e4f313bd8640c6f77c522c4349 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 15:23:19 +0100 Subject: [PATCH 021/142] More merge cruft --- contracts/tokens/SecurityToken.sol | 9 --------- 1 file changed, 9 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 5e14a08c1..d3e840261 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -697,21 +697,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return success */ function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) { -<<<<<<< HEAD if (modules[PERMISSION_KEY].length == 0) { return false; } for (uint8 i = 0; i < modules[PERMISSION_KEY].length; i++) { if (IPermissionManager(modules[PERMISSION_KEY][i]).checkPermission(_delegate, _module, _perm)) { -======= - if (modules[PERMISSIONMANAGER_KEY].length == 0) { - return false; - } - - for (uint8 i = 0; i < modules[PERMISSIONMANAGER_KEY].length; i++) { - if (IPermissionManager(modules[PERMISSIONMANAGER_KEY][i]).checkPermission(_delegate, _module, _perm)) { ->>>>>>> development-1.5.0 return true; } } From 5e57f73981329c0947159337e6f06f41d284268b Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Wed, 3 Oct 2018 18:00:48 +0200 Subject: [PATCH 022/142] finished permission manager changes --- .eslintrc.js | 10 +++ .gitignore | 3 +- .../GeneralPermissionManager.sol | 62 ++++++++++++++++--- test/g_general_permission_manager.js | 56 +++++++++++++++++ 4 files changed, 121 insertions(+), 10 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b173360a3..463539deb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,4 +6,14 @@ module.exports = { "assert": false, "web3": false }, + + "rules": { + "indent": 0, + "camelcase": 0, + "no-unused-vars": 0, + "quotes": 0, + "semi": 0, + "no-undef": 0, + "key-spacing": 0 + } }; diff --git a/.gitignore b/.gitignore index 40890224b..fb4573022 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ coverage.json bridge.log scTopics coverageEnv -/flat \ No newline at end of file +/flat +.eslintrc.js \ No newline at end of file diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index ab4a06f1c..35fb6b7ef 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -8,7 +8,7 @@ import "../Module.sol"; */ contract GeneralPermissionManager is IPermissionManager, Module { - // Mapping used to hold the permissions on the modules provided to delegate + // Mapping used to hold the permissions on the modules provided to delegate, delegate add => modules add => permission uint8 => bool mapping (address => mapping (address => mapping (bytes32 => bool))) public perms; // Mapping hold the delagate details mapping (address => bytes32) public delegateDetails; @@ -113,17 +113,20 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @return bool */ function isDelegate(address _potentialDelegate) public view returns(bool) { + + require(_potentialDelegate != address(0)); + if (delegateDetails[_potentialDelegate] != bytes32(0)) { return true; - }else + }else{ return false; + } } /** * @notice Use to change one or more permissions for a single delegate at once * @param _delegate Ethereum address of the delegate - * @param _module Ethereum contract address of the module - * @param _multiModule Multiple module matching the multiperms, needs to be same length + * @param _multiModules Multiple module matching the multiperms, needs to be same length * @param _multiPerms Multiple permission flag needs to be changed * @return nothing */ @@ -136,23 +139,29 @@ contract GeneralPermissionManager is IPermissionManager, Module { withPerm(CHANGE_PERMISSION) { require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); + require(_multiModules.length != 0 && _multiPerms.length !=0); for(uint8 i=0;i<_multiPerms.length;i++){ bool _currentPerm = !perms[_multiModules[i]][_delegate][_multiPerms[i]]; perms[_multiModules[i]][_delegate][_multiPerms[i]] = _currentPerm; - emit LogChangePermission(_delegate, [_multiModules[i]], _multiPerms[i], _currentPerm, now); + emit ChangePermission(_delegate, _multiModules[i], _multiPerms[i], _currentPerm, now); } } /** * @notice use to return all delegates with a given permission and module + * @param _module Ethereum contract address of the module + * @param _perm Permission flag * @return address[] */ - function getAllDelegatesWithPerm(_module, _perm) public view returns(address[]) { - - address[] memory allDelegatesWithPerm; - for(uint8 i=0;igetModulesByType + for(uint8 i=0; i<_types.length; i++){ + address[] memory _currentTypeModules = ISecurityToken(_tokenAddress).getModulesByType(_types[i]); + + // loop through each modules to get their perms from iModule->getPermissions + for(uint8 a=0; a<_currentTypeModules.length; a++){ + bytes32[] memory _allModulePerms = IModule(_currentTypeModules[a]).getPermissions(); + + // loop through each perm, if it is true, push results into arrays + for (uint8 b=0; b<_allModulePerms.length; b++){ + if(perms[_currentTypeModules[a]][_delegate][_allModulePerms[b]]){ + _allModules.push(_currentTypeModules[a]); + _allPerms.push(_allModulePerms[b]); + } + } + } + } + + return(_allModules, _allPerms); + } diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index cb8f0b1c9..5d9a05780 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -37,6 +37,8 @@ contract('GeneralPermissionManager', accounts => { let account_investor3; let account_investor4; let account_delegate; + let account_delegate2; + let account_delegate3; // investor Details let fromTime = latestTime(); let toTime = latestTime(); @@ -103,6 +105,8 @@ contract('GeneralPermissionManager', accounts => { account_investor1 = accounts[8]; account_investor2 = accounts[9]; account_delegate = accounts[7]; + account_delegate2 = accounts[6]; + account_delegate3 = accounts[5]; // ----------- POLYMATH NETWORK Configuration ------------ @@ -316,6 +320,7 @@ contract('GeneralPermissionManager', accounts => { ); I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); }); + }); describe("General Permission Manager test cases", async() => { @@ -405,6 +410,57 @@ contract('GeneralPermissionManager', accounts => { "CHANGE_PERMISSION", "Wrong permissions"); }); + + it("Should return all delegates", async() => { + await I_GeneralPermissionManager.addDelegate(account_delegate2, delegateDetails, { from: token_owner}); + let tx = await I_GeneralPermissionManager.getAllDelegates.call(); + assert.equal(tx.length, 2); + assert.equal(tx[0], account_delegate); + assert.equal(tx[1], account_delegate2); + }); + + it("Should return false when check is delegate - because user is not a delegate", async() => { + assert.equal(await I_GeneralPermissionManager.isDelegate.call(account_investor1), false); + }); + + it("Should return true when check is delegate - because user is a delegate", async() => { + assert.equal(await I_GeneralPermissionManager.isDelegate.call(account_delegate), true); + }); + + //ideally need to test with another module attached + it("Should provide the permission in bulk", async() => { + await I_GeneralPermissionManager.addDelegate(account_delegate3, delegateDetails, { from: token_owner}); + let tx = await I_GeneralPermissionManager.changePermissionBulk(account_delegate3, [I_GeneralTransferManager.address], ["WHITELIST"], {from: token_owner}); + assert.equal(tx.logs[0].args._delegate, account_delegate3); + }); + + + it("Should provide all delegates with specified permission", async() => { + + await I_GeneralPermissionManager.changePermission(account_delegate2, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); + + let tx = await I_GeneralPermissionManager.getAllDelegatesWithPerm.call(I_GeneralTransferManager.address, "WHITELIST"); + assert.equal(tx.length, 3); + assert.equal(tx[0], account_delegate); + assert.equal(tx[1], account_delegate2); + }); + + //ideally need to test with another module attached + it("Should return all modules and all permission", async() => { + + let tx = await I_GeneralPermissionManager.getAllModulesAndPerms.call(account_delegate, [2], I_SecurityToken.address); + + console.log (tx); + + assert.equal(tx[0][0], I_GeneralTransferManager.address); + assert.equal(tx[1][0], "0x57484954454c4953540000000000000000000000000000000000000000000000"); + + }); + + + + + }); describe("General Permission Manager Factory test cases", async() => { From 98b7a8e476cf7c599f09de41f8479ab9e4d89187 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Wed, 3 Oct 2018 18:18:11 +0200 Subject: [PATCH 023/142] finished permission manager changes --- .../modules/PermissionManager/GeneralPermissionManager.sol | 1 + test/g_general_permission_manager.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 70258c7ea..35fb6b7ef 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -61,6 +61,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { function addDelegate(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { require(_details != bytes32(0), "Delegate details not set"); delegateDetails[_delegate] = _details; + allDelegates.push(_delegate); emit LogAddDelegate(_delegate, _details, now); } diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 5d9a05780..f7d3523ad 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -414,6 +414,7 @@ contract('GeneralPermissionManager', accounts => { it("Should return all delegates", async() => { await I_GeneralPermissionManager.addDelegate(account_delegate2, delegateDetails, { from: token_owner}); let tx = await I_GeneralPermissionManager.getAllDelegates.call(); + console.log(tx); assert.equal(tx.length, 2); assert.equal(tx[0], account_delegate); assert.equal(tx[1], account_delegate2); @@ -440,6 +441,7 @@ contract('GeneralPermissionManager', accounts => { await I_GeneralPermissionManager.changePermission(account_delegate2, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); let tx = await I_GeneralPermissionManager.getAllDelegatesWithPerm.call(I_GeneralTransferManager.address, "WHITELIST"); + console.log(tx); assert.equal(tx.length, 3); assert.equal(tx[0], account_delegate); assert.equal(tx[1], account_delegate2); From f31a00146054a8593e39f0878882e9720ae77523 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 18:23:17 +0100 Subject: [PATCH 024/142] WIP fixes --- contracts/interfaces/ISecurityToken.sol | 16 +- contracts/modules/Burn/TrackedRedemption.sol | 2 +- .../modules/Checkpoint/DividendCheckpoint.sol | 3 +- contracts/tokens/STFactory.sol | 22 +-- contracts/tokens/SecurityToken.sol | 148 ++++++++---------- test/o_security_token.js | 42 +++-- 6 files changed, 109 insertions(+), 124 deletions(-) diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index ced158b9c..a9c3b05a8 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -33,14 +33,14 @@ interface ISecurityToken { * @notice Burn function used to burn the securityToken * @param _value No. of tokens that get burned */ - function burn(uint256 _value) external returns (bool success); + function burn(uint256 _value) external; /** * @notice Burn function used to burn the securityToken on behalf of someone else * @param _from Address for whom to burn tokens * @param _value No. of token that get burned */ - function burnFrom(address _from, uint256 _value) external returns (bool success); + function burnFrom(address _from, uint256 _value) external; event Minted(address indexed _to, uint256 _value); event Burnt(address indexed _burner, uint256 _value); @@ -101,7 +101,7 @@ interface ISecurityToken { * NB - this length may differ from investorCount if the list has not been pruned of zero-balance investors * @return length */ - function getInvestorsLength() external view returns (uint256); + function getInvestors() external view returns (address[]); /** * @notice gets current checkpoint ID @@ -225,7 +225,15 @@ interface ISecurityToken { * @param _value amount of tokens to transfer * @param _data data attached to the transfer by controller to emit in event */ - function forceTransfer(address _from, address _to, uint256 _value, bytes _data) external returns(bool); + function forceTransfer(address _from, address _to, uint256 _value, bytes _data) external; + + /** + * @notice Use by a controller to execute a foced burn + * @param _from address from which to take tokens + * @param _value amount of tokens to transfer + * @param _data data attached to the transfer by controller to emit in event + */ + function forceBurn(address _from, uint256 _value, bytes _data) external; /** * @notice Use by the issuer to permanently disable controller functionality diff --git a/contracts/modules/Burn/TrackedRedemption.sol b/contracts/modules/Burn/TrackedRedemption.sol index f69d8a86a..44a0b1d0e 100644 --- a/contracts/modules/Burn/TrackedRedemption.sol +++ b/contracts/modules/Burn/TrackedRedemption.sol @@ -37,7 +37,7 @@ contract TrackedRedemption is IBurn, Module { * @param _value The number of tokens to redeem */ function redeemTokens(uint256 _value) public { - require(ISecurityToken(securityToken).burnFrom(msg.sender, _value), "Unable to redeem tokens"); + ISecurityToken(securityToken).burnFrom(msg.sender, _value); redeemedTokens[msg.sender] = redeemedTokens[msg.sender].add(_value); emit Redeemed(msg.sender, _value, now); } diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index fc70a9fde..425de3e90 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -131,7 +131,8 @@ contract DividendCheckpoint is ICheckpoint, Module { */ function pushDividendPayment(uint256 _dividendIndex, uint256 _start, uint256 _iterations) public withPerm(DISTRIBUTE) validDividendIndex(_dividendIndex) { Dividend storage dividend = dividends[_dividendIndex]; - uint256 numberInvestors = ISecurityToken(securityToken).getInvestorsLength(); + address[] memory investors = ISecurityToken(securityToken).getInvestors(); + uint256 numberInvestors = investors.length; for (uint256 i = _start; i < Math.min256(numberInvestors, _start.add(_iterations)); i++) { address payee = ISecurityToken(securityToken).investors(i); if ((!dividend.claimed[payee]) && (!dividend.dividendExcluded[payee])) { diff --git a/contracts/tokens/STFactory.sol b/contracts/tokens/STFactory.sol index 6273cc69c..4277a8f29 100644 --- a/contracts/tokens/STFactory.sol +++ b/contracts/tokens/STFactory.sol @@ -10,9 +10,6 @@ contract STFactory is ISTFactory { address public transferManagerFactory; - // Should be set to false when we have more TransferManager options - bool addTransferManager = true; - constructor (address _transferManagerFactory) public { transferManagerFactory = _transferManagerFactory; } @@ -24,20 +21,15 @@ contract STFactory is ISTFactory { function deployToken(string _name, string _symbol, uint8 _decimals, string _tokenDetails, address _issuer, bool _divisible, address _polymathRegistry) external returns (address) { address newSecurityTokenAddress = new SecurityToken( - _name, - _symbol, - _decimals, - _divisible ? 1 : uint256(10)**_decimals, - _tokenDetails, - _polymathRegistry + _name, + _symbol, + _decimals, + _divisible ? 1 : uint256(10)**_decimals, + _tokenDetails, + _polymathRegistry ); - - if (addTransferManager) { - SecurityToken(newSecurityTokenAddress).addModule(transferManagerFactory, "", 0, 0); - } - + SecurityToken(newSecurityTokenAddress).addModule(transferManagerFactory, "", 0, 0); SecurityToken(newSecurityTokenAddress).transferOwnership(_issuer); - return newSecurityTokenAddress; } } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index d3e840261..7f2ef9f1b 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -34,16 +34,16 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint8 patch; } - SemanticVersion public securityTokenVersion; + SemanticVersion securityTokenVersion; // off-chain hash string public tokenDetails; - uint8 public constant PERMISSION_KEY = 1; - uint8 public constant TRANSFER_KEY = 2; - uint8 public constant MINT_KEY = 3; - uint8 public constant CHECKPOINT_KEY = 4; - uint8 public constant BURN_KEY = 5; + uint8 constant PERMISSION_KEY = 1; + uint8 constant TRANSFER_KEY = 2; + uint8 constant MINT_KEY = 3; + uint8 constant CHECKPOINT_KEY = 4; + uint8 constant BURN_KEY = 5; uint256 public granularity; @@ -54,7 +54,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint256 public investorCount; // List of token holders - address[] public investors; + address[] investors; // Use to temporarily halt all transactions bool public transfersFrozen; @@ -68,7 +68,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // address whitelisted by issuer as controller address public controller; - event ModuleDataEvent( + /* event ModuleDataEvent( bytes32 name, address module, address moduleFactory, @@ -76,7 +76,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint8[] moduleTypes, uint256[] moduleIndexes, uint256 nameIndex - ); + ); */ // Struct for module data struct ModuleData { bytes32 name; @@ -91,7 +91,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } // Records added modules - module list should be order agnostic! - mapping (uint8 => address[]) public modules; + mapping (uint8 => address[]) modules; // Records information about the module mapping (address => ModuleData) modulesToData; @@ -106,20 +106,20 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } // Map each investor to a series of checkpoints - mapping (address => Checkpoint[]) public checkpointBalances; + mapping (address => Checkpoint[]) checkpointBalances; // List of checkpoints that relate to total supply - Checkpoint[] public checkpointTotalSupply; + Checkpoint[] checkpointTotalSupply; // Times at which each checkpoint was created - uint256[] public checkpointTimes; + uint256[] checkpointTimes; // List of investors (may not be pruned to remove old investors with current zero balances) - mapping (address => bool) public investorListed; + mapping (address => bool) investorListed; // Emit at the time when module get added event ModuleAdded( - uint8[] indexed _types, + uint8[] _types, bytes32 _name, address _moduleFactory, address _module, @@ -133,13 +133,13 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // Emit when the granularity get changed event GranularityChanged(uint256 _oldGranularity, uint256 _newGranularity); // Emit when Module get removed from the securityToken - event ModuleRemoved(uint8[] indexed _types, address _module, uint256 _timestamp); + event ModuleRemoved(uint8[] _types, address _module, uint256 _timestamp); // Emit when Module get archived from the securityToken - event ModuleArchived(uint8[] indexed _types, address _module, uint256 _timestamp); + event ModuleArchived(uint8[] _types, address _module, uint256 _timestamp); // Emit when Module get unarchived from the securityToken - event ModuleUnarchived(uint8[] indexed _types, address _module, uint256 _timestamp); + event ModuleUnarchived(uint8[] _types, address _module, uint256 _timestamp); // Emit when the budget allocated to a module is changed - event ModuleBudgetChanged(uint8[] indexed _moduleTypes, address _module, uint256 _oldBudget, uint256 _budget); + event ModuleBudgetChanged(uint8[] _moduleTypes, address _module, uint256 _oldBudget, uint256 _budget); // Emit when transfers are frozen or unfrozen event FreezeTransfers(bool _status, uint256 _timestamp); // Emit when new checkpoint created @@ -187,7 +187,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } modifier isMintingAllowed() { - require(!mintingFrozen, "Minting is frozen"); + require(!mintingFrozen, "Minting frozen"); _; } @@ -200,7 +200,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice Revert if called by account which is not a controller */ modifier onlyController() { - require(msg.sender == controller, "Caller not controller"); + require(msg.sender == controller, "Not controller"); require(!controllerDisabled, "Controller disabled"); _; } @@ -234,11 +234,15 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice Function used to attach the module in security token - * @param _moduleFactory Contract address of the module factory that needs to be attached - * @param _data Data used for the intialization of the module factory variables - * @param _maxCost Maximum cost of the Module factory - * @param _budget Budget of the Module factory + * @notice Function used to attach a module to the security token + * @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it + * @dev to control restrictions on transfers. + * @dev You are allowed to add a new moduleType if: + * @dev - there is no existing module of that type yet added + * @dev - the last member of the module list is replacable + * @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 module. (WIP) */ function addModule( address _moduleFactory, @@ -246,35 +250,19 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint256 _maxCost, uint256 _budget ) external onlyOwner nonReentrant { - _addModule(_moduleFactory, _data, _maxCost, _budget); - } - - /** - * @notice _addModule handles the attachment (or replacement) of modules for the ST - * @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it - * @dev to control restrictions on transfers. - * @dev You are allowed to add a new moduleType if: - * @dev - there is no existing module of that type yet added - * @dev - the last member of the module list is replacable - * @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 module. (WIP) - */ - function _addModule(address _moduleFactory, bytes _data, uint256 _maxCost, uint256 _budget) internal { //Check that module exists in registry - will throw otherwise IModuleRegistry(moduleRegistry).useModule(_moduleFactory); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); uint8[] memory moduleTypes = moduleFactory.getTypes(); - /* require(modules[moduleType].length < MAX_MODULES, "Limit of MAX MODULES is reached"); */ uint256 moduleCost = moduleFactory.getSetupCost(); - require(moduleCost <= _maxCost, "Module cost too high"); + require(moduleCost <= _maxCost, "Cost too high"); //Approve fee for module - require(ERC20(polyToken).approve(_moduleFactory, moduleCost), "Insufficient funds for cost"); + require(ERC20(polyToken).approve(_moduleFactory, moduleCost), "Insufficient funds"); //Creates instance of module from factory address module = moduleFactory.deploy(_data); - require(modulesToData[module].module == address(0), "Module already exists"); + require(modulesToData[module].module == address(0), "Module exists"); //Approve ongoing budget - require(ERC20(polyToken).approve(module, _budget), "Insufficient funds for budget"); + require(ERC20(polyToken).approve(module, _budget), "Insufficient funds"); //Add to SecurityToken module map bytes32 moduleName = moduleFactory.getName(); uint256[] memory moduleIndexes = new uint256[](moduleTypes.length); @@ -283,15 +271,16 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint256 j; for (i = 0; i < moduleTypes.length; i++) { for (j = 0; j < i; j++) { - require(moduleTypes[i] != moduleTypes[j], "Bad types"); + require(moduleTypes[i] != moduleTypes[j], "Type mismatch"); } } for (i = 0; i < moduleTypes.length; i++) { moduleIndexes[i] = modules[moduleTypes[i]].length; } - emit ModuleDataEvent(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); - /* modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); */ + /* emit ModuleDataEvent(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); */ + modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); for (i = 0; i < moduleTypes.length; i++) { + modulesToData[module].moduleType[moduleTypes[i]] = true; modules[moduleTypes[i]].push(module); } names[moduleName].push(module); @@ -304,7 +293,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _module address of module to archive */ function archiveModule(address _module) external onlyOwner { - require(!modulesToData[_module].isArchived, "Module already archived"); + require(!modulesToData[_module].isArchived, "Module archived"); require(modulesToData[_module].module != address(0), "Module missing"); emit ModuleArchived(modulesToData[_module].moduleTypes, _module, now); modulesToData[_module].isArchived = true; @@ -315,7 +304,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _module address of module to unarchive */ function unarchiveModule(address _module) external onlyOwner { - require(modulesToData[_module].isArchived, "Module already unarchived"); + require(modulesToData[_module].isArchived, "Module unarchived"); emit ModuleUnarchived(modulesToData[_module].moduleTypes, _module, now); modulesToData[_module].isArchived = false; } @@ -341,13 +330,14 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _module address of module to unarchive */ function removeModule(address _module) external onlyOwner { - require(modulesToData[_module].isArchived, "Module not archived"); + require(modulesToData[_module].isArchived, "Module archived"); require(modulesToData[_module].module != address(0), "Module missing"); emit ModuleRemoved(modulesToData[_module].moduleTypes, _module, now); // Remove from module type list uint8[] memory moduleTypes = modulesToData[_module].moduleTypes; for (uint256 i = 0; i < moduleTypes.length; i++) { _removeModuleWithIndex(moduleTypes[i], modulesToData[_module].moduleIndexes[i]); + modulesToData[_module].moduleType[moduleTypes[i]] = false; } // Remove from module names list uint256 index = modulesToData[_module].nameIndex; @@ -415,9 +405,9 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr require(modulesToData[_module].module != address(0), "Module missing"); uint256 _currentAllowance = IERC20(polyToken).allowance(address(this), _module); if (_budget < _currentAllowance) { - require(IERC20(polyToken).decreaseApproval(_module, _currentAllowance.sub(_budget)), "Insufficient balance to decreaseApproval"); + require(IERC20(polyToken).decreaseApproval(_module, _currentAllowance.sub(_budget)), "Insufficient balance"); } else { - require(IERC20(polyToken).increaseApproval(_module, _budget.sub(_currentAllowance)), "Insufficient balance to increaseApproval"); + require(IERC20(polyToken).increaseApproval(_module, _budget.sub(_currentAllowance)), "Insufficient balance"); } emit ModuleBudgetChanged(modulesToData[_module].moduleTypes, _module, _currentAllowance, _budget); } @@ -436,7 +426,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _granularity granularity level of the token */ function changeGranularity(uint256 _granularity) external onlyOwner { - require(_granularity != 0, "Granularity can not be 0"); + require(_granularity != 0, "Incorrect granularity"); emit GranularityChanged(granularity, _granularity); granularity = _granularity; } @@ -488,8 +478,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * NB - this length may differ from investorCount if list has not been pruned of zero balance investors * @return length */ - function getInvestorsLength() external view returns(uint256) { - return investors.length; + function getInvestors() external view returns(address[]) { + return investors; } /** @@ -565,7 +555,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return bool success */ function transfer(address _to, uint256 _value) public returns (bool success) { - require(_updateTransfer(msg.sender, _to, _value), "Transfer is not valid"); + require(_updateTransfer(msg.sender, _to, _value), "Transfer not valid"); require(super.transfer(_to, _value)); return true; } @@ -578,7 +568,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return bool success */ function transferFrom(address _from, address _to, uint256 _value) public returns(bool) { - require(_updateTransfer(_from, _to, _value), "Transfer is not valid"); + require(_updateTransfer(_from, _to, _value), "Transfer not valid"); require(super.transferFrom(_from, _to, _value)); return true; } @@ -660,9 +650,9 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return success */ function mint(address _investor, uint256 _value) public onlyModuleOrOwner(MINT_KEY) checkGranularity(_value) isMintingAllowed() returns (bool success) { - require(_investor != address(0), "Investor address should not be 0x"); + require(_investor != address(0), "Investor is 0"); _adjustInvestorCount(address(0), _investor, _value); - require(_verifyTransfer(address(0), _investor, _value, true), "Transfer is not valid"); + require(_verifyTransfer(address(0), _investor, _value, true), "Transfer not valid"); _adjustBalanceCheckpoints(_investor); _adjustTotalSupplyCheckpoints(); totalSupply_ = totalSupply_.add(_value); @@ -710,24 +700,22 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return false; } - function _burn(address _from, uint256 _value) internal returns (bool) { + function _burn(address _from, uint256 _value) internal { require(_value <= balances[_from], "Value too high"); - require(_updateTransfer(_from, address(0), _value), "Burn is not valid"); + require(_updateTransfer(_from, address(0), _value), "Transfer not valid"); _adjustTotalSupplyCheckpoints(); balances[_from] = balances[_from].sub(_value); totalSupply_ = totalSupply_.sub(_value); emit Burnt(_from, _value); emit Transfer(_from, address(0), _value); - return true; } /** * @notice Burn function used to burn the securityToken * @param _value No. of tokens that get burned */ - function burn(uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public returns (bool) { - require(_burn(msg.sender, _value), "Invalid burn"); - return true; + function burn(uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public { + _burn(msg.sender, _value); } /** @@ -735,11 +723,10 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _from Address for whom to burn tokens * @param _value No. of tokens that get burned */ - function burnFrom(address _from, uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public returns (bool) { + function burnFrom(address _from, uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public { require(_value <= allowed[_from][msg.sender], "Value too high"); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); - require(_burn(_from, _value), "Invalid burn"); - return true; + _burn(_from, _value); } /** @@ -850,34 +837,33 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _value amount of tokens to transfer * @param _data data attached to the transfer by controller to emit in event */ - function forceTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController returns(bool) { + function forceTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController { require(_to != address(0)); - require(_value <= balances[_from]); - bool verified = _updateTransfer(_from, _to, _value); - balances[_from] = balances[_from].sub(_value); + bool verified = _transfer(_from, _to, _value); balances[_to] = balances[_to].add(_value); - emit ForceTransfer(msg.sender, _from, _to, _value, verified, _data); emit Transfer(_from, _to, _value); - return true; } + function _transfer(address _from, address _to, uint256 _value) internal returns(bool) { + require(_value <= balances[_from]); + bool verified = _updateTransfer(_from, _to, _value); + balances[_from] = balances[_from].sub(_value); + return verified; + } /** * @notice Use by a controller to execute a foced burn * @param _from address from which to take tokens * @param _value amount of tokens to transfer * @param _data data attached to the transfer by controller to emit in event */ - function forceBurn(address _from, uint256 _value, bytes _data) public onlyController returns(bool) { - require(_value <= balances[_from], "Value too high"); - bool verified = _updateTransfer(_from, address(0), _value); + function forceBurn(address _from, uint256 _value, bytes _data) public onlyController { + bool verified = _transfer(_from, address(0), _value); _adjustTotalSupplyCheckpoints(); - balances[_from] = balances[_from].sub(_value); totalSupply_ = totalSupply_.sub(_value); emit ForceBurn(msg.sender, _from, _value, verified, _data); emit Burnt(_from, _value); emit Transfer(_from, address(0), _value); - return true; } /** diff --git a/test/o_security_token.js b/test/o_security_token.js index 1217c6c22..cd096ac72 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -18,7 +18,6 @@ const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManage const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); -const TokenBurner = artifacts.require('./MockTokenBurner.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -69,7 +68,6 @@ contract('SecurityToken', accounts => { let I_MRProxied; let I_CappedSTO; let I_PolyToken; - let I_TokenBurner; let I_PolymathRegistry; // SecurityToken Details (Launched ST on the behalf of the issuer) @@ -264,12 +262,13 @@ contract('SecurityToken', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + console.log(log.args); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal(web3.utils.toUtf8(log.args._name),"GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); assert.notEqual( @@ -480,7 +479,7 @@ contract('SecurityToken', accounts => { const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + 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); }); @@ -515,9 +514,7 @@ contract('SecurityToken', accounts => { assert.equal(moduleData[1], I_CappedSTO.address); assert.equal(moduleData[2], I_CappedSTOFactory.address); assert.equal(moduleData[3], false); - assert.equal(moduleData[4], 3); - assert.equal(moduleData[5], 0); - assert.equal(moduleData[6], 0); + assert.equal(moduleData[4][0], 3); }); it("Should get the modules of the securityToken by index (not added into the security token yet)", async () => { @@ -561,29 +558,29 @@ contract('SecurityToken', accounts => { assert.equal(log.logs[0].args._newDetails, "new token details"); }); - it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async() => { + it("Should fail to remove the module - module not archived", async() => { let errorThrown = false; try { - let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp }); + let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner }); } catch (error) { - console.log(`Test Case passed by restricting the unknown account to call removeModule of the securityToken`); + console.log(` tx -> Failed because address doesn't exist`); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); - }); + }) - it("Should fail to remove the module - module not archived", async() => { + it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async() => { let errorThrown = false; try { - let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner }); + let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp }); } catch (error) { - console.log(` tx -> Failed because address doesn't exist`); + console.log(`Test Case passed by restricting the unknown account to call removeModule of the securityToken`); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); - }) + }); it("Should fail to remove the module - incorrect address", async() => { let errorThrown = false; @@ -601,7 +598,7 @@ contract('SecurityToken', accounts => { let key = await takeSnapshot(); await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._types[0], transferManagerKey); assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); await revertToSnapshot(key); }); @@ -615,7 +612,7 @@ contract('SecurityToken', accounts => { it("Should successfully archive the general transfer manager module from the securityToken", async() => { let tx = await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._types[0], transferManagerKey); assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); @@ -634,7 +631,7 @@ contract('SecurityToken', accounts => { it("Should successfully unarchive the general transfer manager module from the securityToken", async() => { let tx = await I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from : token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._types[0], transferManagerKey); assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); @@ -671,7 +668,7 @@ contract('SecurityToken', accounts => { it("Should change the budget of the module", async() => { let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, (100 * Math.pow(10, 18)),{ from : token_owner}); - assert.equal(tx.logs[1].args._moduleType, stoKey); + assert.equal(tx.logs[1].args._moduleTypes[0], stoKey); assert.equal(tx.logs[1].args._module, I_CappedSTO.address); assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); }); @@ -702,13 +699,14 @@ contract('SecurityToken', accounts => { // Jump time await increaseTime(5000); // Fallback transaction + console.log("BEFORE"); await web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO.address, gas: 2100000, value: web3.utils.toWei('1', 'ether') }); - + console.log("AFTER"); assert.equal( (await I_CappedSTO.getRaised.call(0)) .dividedBy(new BigNumber(10).pow(18)) @@ -742,7 +740,7 @@ contract('SecurityToken', accounts => { let errorThrown = false; // Add permission to the deletgate (A regesteration process) await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: token_owner}); - let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); + let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); try { await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp }); From a37a7762f3394a114603f5e6ee7b33e052deab48 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 21:29:28 +0100 Subject: [PATCH 025/142] Still too big --- contracts/ModuleRegistry.sol | 11 ++++++- .../ProxyFactory/USDTieredSTOProxyFactory.sol | 9 +++--- contracts/tokens/SecurityToken.sol | 30 +++++-------------- test/o_security_token.js | 24 +++++++-------- 4 files changed, 33 insertions(+), 41 deletions(-) diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index 60e5478a4..188745e98 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -155,7 +155,16 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } require(getUint(Encoder.getKey('registry', _moduleFactory)) == 0, "Module factory should not be pre-registered"); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); - require(moduleFactory.getTypes().length != 0, "Factory must have type"); + //Enforce type uniqueness + uint256 i; + uint256 j; + uint8[] memory moduleTypes = moduleFactory.getTypes(); + for (i = 0; i < moduleTypes.length; i++) { + for (j = 0; j < i; j++) { + require(moduleTypes[i] != moduleTypes[j], "Type mismatch"); + } + } + require(moduleTypes.length != 0, "Factory must have type"); // NB - here we index by the first type of the module. uint8 moduleType = moduleFactory.getTypes()[0]; set(Encoder.getKey('registry', _moduleFactory), uint256(moduleType)); diff --git a/contracts/modules/STO/ProxyFactory/USDTieredSTOProxyFactory.sol b/contracts/modules/STO/ProxyFactory/USDTieredSTOProxyFactory.sol index dc4d6c628..1f241d8cc 100644 --- a/contracts/modules/STO/ProxyFactory/USDTieredSTOProxyFactory.sol +++ b/contracts/modules/STO/ProxyFactory/USDTieredSTOProxyFactory.sol @@ -5,17 +5,15 @@ import "../../../interfaces/IUSDTieredSTOProxy.sol"; contract USDTieredSTOProxyFactory is IUSDTieredSTOProxy { - - constructor() public { } - + /** * @notice deploys the STO. * @param _securityToken Contract address of the securityToken * @param _polyAddress Contract address of the PolyToken. - * @param _factoryAddress Contract address of the factory + * @param _factoryAddress Contract address of the factory * @return address Address of the deployed STO */ function deploySTO(address _securityToken, address _polyAddress, address _factoryAddress) external returns (address) { @@ -31,4 +29,5 @@ contract USDTieredSTOProxyFactory is IUSDTieredSTOProxy { function getInitFunction(address _contractAddress) external returns (bytes4) { return USDTieredSTO(_contractAddress).getInitFunction(); } -} \ No newline at end of file + +} diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 7f2ef9f1b..d9bdfebd5 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -68,15 +68,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // address whitelisted by issuer as controller address public controller; - /* event ModuleDataEvent( - bytes32 name, - address module, - address moduleFactory, - bool isArchived, - uint8[] moduleTypes, - uint256[] moduleIndexes, - uint256 nameIndex - ); */ // Struct for module data struct ModuleData { bytes32 name; @@ -86,7 +77,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint8[] moduleTypes; uint256[] moduleIndexes; uint256 nameIndex; - mapping (uint8 => bool) moduleType; mapping (uint8 => uint256) moduleIndex; } @@ -160,9 +150,13 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr function _isModule(address _module, uint8 _type) internal view returns (bool) { require(modulesToData[_module].module == _module, "Address mismatch"); - require(modulesToData[_module].moduleType[_type], "Type mismatch"); require(!modulesToData[_module].isArchived, "Module archived"); - return true; + for (uint256 i = 0; i < modulesToData[_module].moduleTypes.length; i++) { + if (modulesToData[_module].moduleTypes[i] == _type) { + return true; + } + } + return false; } // Require msg.sender to be the specified module type @@ -266,21 +260,13 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr //Add to SecurityToken module map bytes32 moduleName = moduleFactory.getName(); uint256[] memory moduleIndexes = new uint256[](moduleTypes.length); - //Enforce type uniqueness uint256 i; - uint256 j; - for (i = 0; i < moduleTypes.length; i++) { - for (j = 0; j < i; j++) { - require(moduleTypes[i] != moduleTypes[j], "Type mismatch"); - } - } for (i = 0; i < moduleTypes.length; i++) { moduleIndexes[i] = modules[moduleTypes[i]].length; } - /* emit ModuleDataEvent(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); */ modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); for (i = 0; i < moduleTypes.length; i++) { - modulesToData[module].moduleType[moduleTypes[i]] = true; + /* modulesToData[module].moduleType[moduleTypes[i]] = true; */ modules[moduleTypes[i]].push(module); } names[moduleName].push(module); @@ -337,7 +323,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint8[] memory moduleTypes = modulesToData[_module].moduleTypes; for (uint256 i = 0; i < moduleTypes.length; i++) { _removeModuleWithIndex(moduleTypes[i], modulesToData[_module].moduleIndexes[i]); - modulesToData[_module].moduleType[moduleTypes[i]] = false; + /* modulesToData[_module].moduleType[moduleTypes[i]] = false; */ } // Remove from module names list uint256 index = modulesToData[_module].nameIndex; diff --git a/test/o_security_token.js b/test/o_security_token.js index cd096ac72..68b3d6816 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -1106,15 +1106,14 @@ contract('SecurityToken', accounts => { it("Should check that the list of investors is correct", async ()=> { // Hardcode list of expected accounts based on transfers above - let investorsLength = await I_SecurityToken.getInvestorsLength(); - console.log(JSON.stringify(investorsLength)); + + let investors = await I_SecurityToken.getInvestors(); let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1, account_temp]; - assert.equal(investorsLength.toNumber(), 4); - console.log("Total Seen Investors: " + investorsLength.toNumber()); - for (let i = 0; i < investorsLength.toNumber(); i++) { - let investor = await I_SecurityToken.investors(i); - assert.equal(investor, expectedAccounts[i]); + for (let i = 0; i < expectedAccounts.length; i++) { + assert.equal(investors[i], expectedAccounts[i]); } + assert.equal(investors.length, 4); + console.log("Total Seen Investors: " + investors.length); }); it("Should fail to set controller status because msg.sender not owner", async() => { let errorThrown = false; @@ -1196,14 +1195,13 @@ contract('SecurityToken', accounts => { it("Should prune investor length", async ()=> { await I_SecurityToken.pruneInvestors(0, 10, {from: token_owner}); // Hardcode list of expected accounts based on transfers above - let investorsLength = (await I_SecurityToken.getInvestorsLength.call()).toNumber(); + + let investors = await I_SecurityToken.getInvestors.call(); let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1]; - assert.equal(investorsLength, 3); - console.log("Total Seen Investors: " + investorsLength); - for (let i = 0; i < investorsLength; i++) { - let investor = await I_SecurityToken.investors(i); - assert.equal(investor, expectedAccounts[i]); + for (let i = 0; i < expectedAccounts.length; i++) { + assert.equal(investors[i], expectedAccounts[i]); } + assert.equal(investors.length, 3); }); it("Should check the balance of investor at checkpoint", async() => { From 5c5dbd50df23daa42a8a034f2bbc60cedbef202e Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 22:16:55 +0100 Subject: [PATCH 026/142] Working --- contracts/libraries/TokenLib.sol | 152 +++++++++++++++++++++++++++++ contracts/tokens/SecurityToken.sol | 107 +++++--------------- migrations/2_deploy_contracts.js | 17 ++-- 3 files changed, 186 insertions(+), 90 deletions(-) create mode 100644 contracts/libraries/TokenLib.sol diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol new file mode 100644 index 000000000..76af88d5d --- /dev/null +++ b/contracts/libraries/TokenLib.sol @@ -0,0 +1,152 @@ +pragma solidity ^0.4.24; + +import "../modules/PermissionManager/IPermissionManager.sol"; + +library TokenLib { + + // Struct for module data + struct ModuleData { + bytes32 name; + address module; + address moduleFactory; + bool isArchived; + uint8[] moduleTypes; + uint256[] moduleIndexes; + uint256 nameIndex; + mapping (uint8 => uint256) moduleIndex; + } + + // Structures to maintain checkpoints of balances for governance / dividends + struct Checkpoint { + uint256 checkpointId; + uint256 value; + } + + // Emit when Module get archived from the securityToken + event ModuleArchived(uint8[] _types, address _module, uint256 _timestamp); + // Emit when Module get unarchived from the securityToken + event ModuleUnarchived(uint8[] _types, address _module, uint256 _timestamp); + + /** + * @notice Archives a module attached to the SecurityToken + * @param _moduleData storage data + * @param _module address of module to archive + */ + function archiveModule(ModuleData storage _moduleData, address _module) public { + require(!_moduleData.isArchived, "Module archived"); + require(_moduleData.module != address(0), "Module missing"); + emit ModuleArchived(_moduleData.moduleTypes, _module, now); + _moduleData.isArchived = true; + } + + /** + * @notice Unarchives a module attached to the SecurityToken + * @param _moduleData storage data + * @param _module address of module to unarchive + */ + function unarchiveModule(ModuleData storage _moduleData, address _module) public { + require(_moduleData.isArchived, "Module unarchived"); + emit ModuleUnarchived(_moduleData.moduleTypes, _module, now); + _moduleData.isArchived = false; + } + + /** + * @notice Validate permissions with PermissionManager if it exists, If no Permission return false + * @dev Note that IModule withPerm will allow ST owner all permissions anyway + * @dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions) + * @param _modules storage data + * @param _delegate address of delegate + * @param _module address of PermissionManager module + * @param _perm the permissions + * @return success + */ + function checkPermission(address[] storage _modules, address _delegate, address _module, bytes32 _perm) public returns(bool) { + if (_modules.length == 0) { + return false; + } + + for (uint8 i = 0; i < _modules.length; i++) { + if (IPermissionManager(_modules[i]).checkPermission(_delegate, _module, _perm)) { + return true; + } + } + + return false; + } + + /** + * @notice Queries value at a defined checkpoint + * @param _checkpoints is array of Checkpoint objects + * @param _checkpointId Checkpoint ID to query + * @param _currentValue Current value of checkpoint + * @return uint256 + */ + function getValueAt(Checkpoint[] storage _checkpoints, uint256 _checkpointId, uint256 _currentValue) public returns(uint256) { + //Checkpoint id 0 is when the token is first created - everyone has a zero balance + if (_checkpointId == 0) { + return 0; + } + if (_checkpoints.length == 0) { + return _currentValue; + } + if (_checkpoints[0].checkpointId >= _checkpointId) { + return _checkpoints[0].value; + } + if (_checkpoints[_checkpoints.length - 1].checkpointId < _checkpointId) { + return _currentValue; + } + if (_checkpoints[_checkpoints.length - 1].checkpointId == _checkpointId) { + return _checkpoints[_checkpoints.length - 1].value; + } + uint256 min = 0; + uint256 max = _checkpoints.length - 1; + while (max > min) { + uint256 mid = (max + min) / 2; + if (_checkpoints[mid].checkpointId == _checkpointId) { + max = mid; + break; + } + if (_checkpoints[mid].checkpointId < _checkpointId) { + min = mid + 1; + } else { + max = mid; + } + } + return _checkpoints[max].value; + } + + /** + * @notice store the changes to the checkpoint objects + * @param _checkpoints the affected checkpoint object array + * @param _newValue the new value that needs to be stored + */ + function adjustCheckpoints(TokenLib.Checkpoint[] storage _checkpoints, uint256 _newValue, uint256 _currentCheckpointId) public { + //No checkpoints set yet + if (_currentCheckpointId == 0) { + return; + } + //No previous checkpoint data - add current balance against checkpoint + if (_checkpoints.length == 0) { + _checkpoints.push( + TokenLib.Checkpoint({ + checkpointId: _currentCheckpointId, + value: _newValue + }) + ); + return; + } + //No new checkpoints since last update + if (_checkpoints[_checkpoints.length - 1].checkpointId == _currentCheckpointId) { + return; + } + //New checkpoint, so record balance + _checkpoints.push( + TokenLib.Checkpoint({ + checkpointId: _currentCheckpointId, + value: _newValue + }) + ); + } + + +} diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index d9bdfebd5..d56a40404 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -7,12 +7,12 @@ import "../interfaces/IModuleFactory.sol"; import "../interfaces/IModuleRegistry.sol"; import "../interfaces/IFeatureRegistry.sol"; import "../modules/TransferManager/ITransferManager.sol"; -import "../modules/PermissionManager/IPermissionManager.sol"; import "../RegistryUpdater.sol"; import "../libraries/Util.sol"; import "openzeppelin-solidity/contracts/ReentrancyGuard.sol"; import "openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol"; import "openzeppelin-solidity/contracts/token/ERC20/DetailedERC20.sol"; +import "../libraries/TokenLib.sol"; /** * @title Security Token contract @@ -68,38 +68,20 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // address whitelisted by issuer as controller address public controller; - // Struct for module data - struct ModuleData { - bytes32 name; - address module; - address moduleFactory; - bool isArchived; - uint8[] moduleTypes; - uint256[] moduleIndexes; - uint256 nameIndex; - mapping (uint8 => uint256) moduleIndex; - } - // Records added modules - module list should be order agnostic! mapping (uint8 => address[]) modules; // Records information about the module - mapping (address => ModuleData) modulesToData; + mapping (address => TokenLib.ModuleData) modulesToData; // Records added module names - module list should be order agnostic! mapping (bytes32 => address[]) names; - // Structures to maintain checkpoints of balances for governance / dividends - struct Checkpoint { - uint256 checkpointId; - uint256 value; - } - // Map each investor to a series of checkpoints - mapping (address => Checkpoint[]) checkpointBalances; + mapping (address => TokenLib.Checkpoint[]) checkpointBalances; // List of checkpoints that relate to total supply - Checkpoint[] checkpointTotalSupply; + TokenLib.Checkpoint[] checkpointTotalSupply; // Times at which each checkpoint was created uint256[] checkpointTimes; @@ -122,12 +104,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr event UpdateTokenDetails(string _oldDetails, string _newDetails); // Emit when the granularity get changed event GranularityChanged(uint256 _oldGranularity, uint256 _newGranularity); - // Emit when Module get removed from the securityToken - event ModuleRemoved(uint8[] _types, address _module, uint256 _timestamp); // Emit when Module get archived from the securityToken event ModuleArchived(uint8[] _types, address _module, uint256 _timestamp); // Emit when Module get unarchived from the securityToken event ModuleUnarchived(uint8[] _types, address _module, uint256 _timestamp); + // Emit when Module get removed from the securityToken + event ModuleRemoved(uint8[] _types, address _module, uint256 _timestamp); // Emit when the budget allocated to a module is changed event ModuleBudgetChanged(uint8[] _moduleTypes, address _module, uint256 _oldBudget, uint256 _budget); // Emit when transfers are frozen or unfrozen @@ -264,7 +246,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr for (i = 0; i < moduleTypes.length; i++) { moduleIndexes[i] = modules[moduleTypes[i]].length; } - modulesToData[module] = ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); + modulesToData[module] = TokenLib.ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); for (i = 0; i < moduleTypes.length; i++) { /* modulesToData[module].moduleType[moduleTypes[i]] = true; */ modules[moduleTypes[i]].push(module); @@ -279,10 +261,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _module address of module to archive */ function archiveModule(address _module) external onlyOwner { - require(!modulesToData[_module].isArchived, "Module archived"); + TokenLib.archiveModule(modulesToData[_module], _module); + /* require(!modulesToData[_module].isArchived, "Module archived"); require(modulesToData[_module].module != address(0), "Module missing"); emit ModuleArchived(modulesToData[_module].moduleTypes, _module, now); - modulesToData[_module].isArchived = true; + modulesToData[_module].isArchived = true; */ } /** @@ -290,9 +273,10 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _module address of module to unarchive */ function unarchiveModule(address _module) external onlyOwner { - require(modulesToData[_module].isArchived, "Module unarchived"); + TokenLib.unarchiveModule(modulesToData[_module], _module); + /* require(modulesToData[_module].isArchived, "Module unarchived"); emit ModuleUnarchived(modulesToData[_module].moduleTypes, _module, now); - modulesToData[_module].isArchived = false; + modulesToData[_module].isArchived = false; */ } function _removeModuleWithIndex(uint8 _type, uint256 _index) internal { @@ -490,7 +474,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice adjust totalsupply at checkpoint after minting or burning tokens */ function _adjustTotalSupplyCheckpoints() internal { - _adjustCheckpoints(checkpointTotalSupply, totalSupply()); + TokenLib.adjustCheckpoints(checkpointTotalSupply, totalSupply(), currentCheckpointId); + /* _adjustCheckpoints(checkpointTotalSupply, totalSupply()); */ } /** @@ -498,7 +483,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _investor address of the token holder affected */ function _adjustBalanceCheckpoints(address _investor) internal { - _adjustCheckpoints(checkpointBalances[_investor], balanceOf(_investor)); + TokenLib.adjustCheckpoints(checkpointBalances[_investor], balanceOf(_investor), currentCheckpointId); + /* _adjustCheckpoints(checkpointBalances[_investor], balanceOf(_investor)); */ } /** @@ -506,7 +492,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _checkpoints the affected checkpoint object array * @param _newValue the new value that needs to be stored */ - function _adjustCheckpoints(Checkpoint[] storage _checkpoints, uint256 _newValue) internal { + /* function _adjustCheckpoints(TokenLib.Checkpoint[] storage _checkpoints, uint256 _newValue) internal { //No checkpoints set yet if (currentCheckpointId == 0) { return; @@ -514,7 +500,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr //No previous checkpoint data - add current balance against checkpoint if (_checkpoints.length == 0) { _checkpoints.push( - Checkpoint({ + TokenLib.Checkpoint({ checkpointId: currentCheckpointId, value: _newValue }) @@ -527,12 +513,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } //New checkpoint, so record balance _checkpoints.push( - Checkpoint({ + TokenLib.Checkpoint({ checkpointId: currentCheckpointId, value: _newValue }) ); - } + } */ /** * @notice Overloaded version of the transfer function @@ -673,7 +659,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return success */ function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) { - if (modules[PERMISSION_KEY].length == 0) { + return TokenLib.checkPermission(modules[PERMISSION_KEY], _delegate, _module, _perm); + /* if (modules[PERMISSION_KEY].length == 0) { return false; } @@ -683,7 +670,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } } - return false; + return false; */ } function _burn(address _from, uint256 _value) internal { @@ -741,49 +728,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return uint256 */ function totalSupplyAt(uint256 _checkpointId) external view returns(uint256) { - return _getValueAt(checkpointTotalSupply, _checkpointId, totalSupply()); - } - - /** - * @notice Queries value at a defined checkpoint - * @param checkpoints is array of Checkpoint objects - * @param _checkpointId Checkpoint ID to query - * @param _currentValue Current value of checkpoint - * @return uint256 - */ - function _getValueAt(Checkpoint[] storage checkpoints, uint256 _checkpointId, uint256 _currentValue) internal view returns(uint256) { require(_checkpointId <= currentCheckpointId); - //Checkpoint id 0 is when the token is first created - everyone has a zero balance - if (_checkpointId == 0) { - return 0; - } - if (checkpoints.length == 0) { - return _currentValue; - } - if (checkpoints[0].checkpointId >= _checkpointId) { - return checkpoints[0].value; - } - if (checkpoints[checkpoints.length - 1].checkpointId < _checkpointId) { - return _currentValue; - } - if (checkpoints[checkpoints.length - 1].checkpointId == _checkpointId) { - return checkpoints[checkpoints.length - 1].value; - } - uint256 min = 0; - uint256 max = checkpoints.length - 1; - while (max > min) { - uint256 mid = (max + min) / 2; - if (checkpoints[mid].checkpointId == _checkpointId) { - max = mid; - break; - } - if (checkpoints[mid].checkpointId < _checkpointId) { - min = mid + 1; - } else { - max = mid; - } - } - return checkpoints[max].value; + return TokenLib.getValueAt(checkpointTotalSupply, _checkpointId, totalSupply()); } /** @@ -792,7 +738,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _checkpointId Checkpoint ID to query as of */ function balanceOfAt(address _investor, uint256 _checkpointId) public view returns(uint256) { - return _getValueAt(checkpointBalances[_investor], _checkpointId, balanceOf(_investor)); + require(_checkpointId <= currentCheckpointId); + return TokenLib.getValueAt(checkpointBalances[_investor], _checkpointId, balanceOf(_investor)); } /** diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 4a78f3ec2..fd2c27bb0 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -17,8 +17,7 @@ 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') -const VersionUtils = artifacts.require('./VersionUtils.sol'); -const Util = artifacts.require('./Util.sol'); +const TokenLib = artifacts.require('./TokenLib.sol'); let BigNumber = require('bignumber.js'); const cappedSTOSetupCost = new BigNumber(20000).times(new BigNumber(10).pow(18)); // 20K POLY fee @@ -128,14 +127,12 @@ module.exports = function (deployer, network, accounts) { }).then((_polymathRegistry) => { polymathRegistry = _polymathRegistry; return polymathRegistry.changeAddress("PolyToken", PolyToken, {from: PolymathAccount}); - // }).then(() => { - // // Deploy libraries - // return deployer.deploy(VersionUtils, {from: PolymathAccount}); - // }).then(() => { - // return deployer.deploy(Util, {from: PolymathAccount}); - // }).then(() => { - // // Link libraries - // return deployer.link(VersionUtils, ModuleRegistry); + }).then(() => { + // Deploy libraries + return deployer.deploy(TokenLib, {from: PolymathAccount}); + }).then(() => { + // Link libraries + return deployer.link(TokenLib, STFactory); // }).then(() => { // return deployer.link(VersionUtils, SecurityTokenRegistry); // }).then(() => { From 80bfbb1808034e879a626d948bee8571e8682928 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 22:18:09 +0100 Subject: [PATCH 027/142] Remove commented lines --- contracts/tokens/SecurityToken.sol | 52 +----------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index d56a40404..0ec644503 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -262,10 +262,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function archiveModule(address _module) external onlyOwner { TokenLib.archiveModule(modulesToData[_module], _module); - /* require(!modulesToData[_module].isArchived, "Module archived"); - require(modulesToData[_module].module != address(0), "Module missing"); - emit ModuleArchived(modulesToData[_module].moduleTypes, _module, now); - modulesToData[_module].isArchived = true; */ } /** @@ -274,9 +270,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function unarchiveModule(address _module) external onlyOwner { TokenLib.unarchiveModule(modulesToData[_module], _module); - /* require(modulesToData[_module].isArchived, "Module unarchived"); - emit ModuleUnarchived(modulesToData[_module].moduleTypes, _module, now); - modulesToData[_module].isArchived = false; */ } function _removeModuleWithIndex(uint8 _type, uint256 _index) internal { @@ -487,39 +480,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr /* _adjustCheckpoints(checkpointBalances[_investor], balanceOf(_investor)); */ } - /** - * @notice store the changes to the checkpoint objects - * @param _checkpoints the affected checkpoint object array - * @param _newValue the new value that needs to be stored - */ - /* function _adjustCheckpoints(TokenLib.Checkpoint[] storage _checkpoints, uint256 _newValue) internal { - //No checkpoints set yet - if (currentCheckpointId == 0) { - return; - } - //No previous checkpoint data - add current balance against checkpoint - if (_checkpoints.length == 0) { - _checkpoints.push( - TokenLib.Checkpoint({ - checkpointId: currentCheckpointId, - value: _newValue - }) - ); - return; - } - //No new checkpoints since last update - if (_checkpoints[_checkpoints.length - 1].checkpointId == currentCheckpointId) { - return; - } - //New checkpoint, so record balance - _checkpoints.push( - TokenLib.Checkpoint({ - checkpointId: currentCheckpointId, - value: _newValue - }) - ); - } */ - /** * @notice Overloaded version of the transfer function * @param _to receiver of transfer @@ -660,17 +620,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) { return TokenLib.checkPermission(modules[PERMISSION_KEY], _delegate, _module, _perm); - /* if (modules[PERMISSION_KEY].length == 0) { - return false; - } - - for (uint8 i = 0; i < modules[PERMISSION_KEY].length; i++) { - if (IPermissionManager(modules[PERMISSION_KEY][i]).checkPermission(_delegate, _module, _perm)) { - return true; - } - } - - return false; */ } function _burn(address _from, uint256 _value) internal { @@ -784,6 +733,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr balances[_from] = balances[_from].sub(_value); return verified; } + /** * @notice Use by a controller to execute a foced burn * @param _from address from which to take tokens From 5a7657b94c6a319cff8222175460ac9269075ecb Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 22:29:28 +0100 Subject: [PATCH 028/142] Fix test cases --- contracts/libraries/TokenLib.sol | 4 ++-- test/b_capped_sto.js | 14 +++++++------- test/c_checkpoints.js | 4 ++-- test/d_count_transfer_manager.js | 8 ++++---- test/e_erc20_dividends.js | 8 ++++---- test/f_ether_dividends.js | 8 ++++---- test/g_general_permission_manager.js | 8 ++++---- test/h_general_transfer_manager.js | 8 ++++---- test/i_Issuance.js | 8 ++++---- test/j_manual_approval_transfer_manager.js | 10 +++++----- test/k_module_registry.js | 4 ++-- test/l_percentage_transfer_manager.js | 8 ++++---- test/m_presale_sto.js | 6 +++--- test/n_security_token_registry.js | 4 ++-- test/p_usd_tiered_sto.js | 12 ++++++------ test/q_usd_tiered_sto_sim.js | 6 +++--- test/r_concurrent_STO.js | 10 +++++----- test/s_v130_to_v140_upgrade.js | 6 +++--- test/t_security_token_registry_proxy.js | 2 +- test/v_tracked_redemptions.js | 6 +++--- 20 files changed, 72 insertions(+), 72 deletions(-) diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index 76af88d5d..8fa281d26 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -60,7 +60,7 @@ library TokenLib { * @param _perm the permissions * @return success */ - function checkPermission(address[] storage _modules, address _delegate, address _module, bytes32 _perm) public returns(bool) { + function checkPermission(address[] storage _modules, address _delegate, address _module, bytes32 _perm) public view returns(bool) { if (_modules.length == 0) { return false; } @@ -81,7 +81,7 @@ library TokenLib { * @param _currentValue Current value of checkpoint * @return uint256 */ - function getValueAt(Checkpoint[] storage _checkpoints, uint256 _checkpointId, uint256 _currentValue) public returns(uint256) { + function getValueAt(Checkpoint[] storage _checkpoints, uint256 _checkpointId, uint256 _currentValue) public view returns(uint256) { //Checkpoint id 0 is when the token is first created - everyone has a zero balance if (_checkpointId == 0) { return 0; diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index a07d6b864..795bfc843 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -269,7 +269,7 @@ contract('CappedSTO', accounts => { const log = await promisifyLogWatch(I_SecurityToken_ETH.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); }); @@ -358,7 +358,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver]); const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); }); @@ -729,7 +729,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH2, endTime_ETH2, cap, rate, [E_fundRaiseType], account_fundsReceiver]); const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); }); @@ -839,7 +839,7 @@ contract('CappedSTO', accounts => { for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(tx.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); } @@ -886,7 +886,7 @@ contract('CappedSTO', accounts => { const log = await promisifyLogWatch(I_SecurityToken_POLY.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); }); @@ -906,7 +906,7 @@ contract('CappedSTO', accounts => { const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); }); @@ -1264,7 +1264,7 @@ contract('CappedSTO', accounts => { const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); }); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index a9094c6c5..7f6a85960 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -215,7 +215,7 @@ contract('Checkpoints', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -224,7 +224,7 @@ contract('Checkpoints', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 0e588a068..c334e0d0d 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -256,7 +256,7 @@ contract('CountTransferManager', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -265,7 +265,7 @@ contract('CountTransferManager', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -287,7 +287,7 @@ contract('CountTransferManager', accounts => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); const tx = await I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), @@ -300,7 +300,7 @@ contract('CountTransferManager', accounts => { it("Should successfully attach the CountTransferManager with the security token", async () => { const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index b2d34f577..e21073f06 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -249,7 +249,7 @@ contract('ERC20DividendCheckpoint', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -258,7 +258,7 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -280,7 +280,7 @@ contract('ERC20DividendCheckpoint', accounts => { await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), @@ -293,7 +293,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index c31197c0a..c02698e87 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -250,7 +250,7 @@ contract('EtherDividendCheckpoint', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -259,7 +259,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -281,7 +281,7 @@ contract('EtherDividendCheckpoint', accounts => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), @@ -294,7 +294,7 @@ contract('EtherDividendCheckpoint', accounts => { it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index da5a8a3f1..b59ad25f1 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -264,7 +264,7 @@ contract('GeneralPermissionManager', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -273,7 +273,7 @@ contract('GeneralPermissionManager', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -294,7 +294,7 @@ contract('GeneralPermissionManager', accounts => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), @@ -307,7 +307,7 @@ contract('GeneralPermissionManager', accounts => { it("Should successfully attach the General permission manager factory with the security token", async () => { const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 76b4be249..0c4deb6c8 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -251,7 +251,7 @@ contract('GeneralTransferManager', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -260,7 +260,7 @@ contract('GeneralTransferManager', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -289,7 +289,7 @@ contract('GeneralTransferManager', accounts => { it("Should successfully attach the STO factory with the security token", async () => { let bytesSTO = encodeModuleCall(STOParameters, [latestTime() + duration.seconds(1000), latestTime() + duration.days(40), cap, someString]); const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), stoKey, "DummySTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), stoKey, "DummySTO doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), @@ -301,7 +301,7 @@ contract('GeneralTransferManager', accounts => { it("Should successfully attach the permission manager factory with the security token", async () => { const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, 0, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 4cfe448d3..a9c502252 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -250,7 +250,7 @@ contract('Issuance', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -259,7 +259,7 @@ contract('Issuance', accounts => { }); it("POLYMATH: Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); @@ -287,7 +287,7 @@ contract('Issuance', accounts => { const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: account_polymath }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), @@ -320,7 +320,7 @@ contract('Issuance', accounts => { it("Should add the delegate with permission", async() => { //First attach a permission manager to the token await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: account_polymath}); - let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); + let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); // Add permission to the deletgate (A regesteration process) await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath}); diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 4a1a6bd5c..08a69c318 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -265,12 +265,12 @@ contract('ManualApprovalTransferManager', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal(web3.utils.toUtf8(log.args._name), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -349,7 +349,7 @@ contract('ManualApprovalTransferManager', accounts => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); const tx = await I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), @@ -363,7 +363,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManager module was not added"); I_ManualApprovalTransferManager = ManualApprovalTransferManager.at(tx.logs[2].args._module); }); @@ -653,7 +653,7 @@ contract('ManualApprovalTransferManager', accounts => { }, [1]); const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); let name = web3.utils.toUtf8(tx.logs[2].args._name); assert.equal(name, "CountTransferManager", "CountTransferManager module was not added"); I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index a7ed18719..ae5bfb434 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -428,7 +428,7 @@ contract('ModuleRegistry', accounts => { let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner}); - assert.equal(tx.logs[2].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), @@ -444,7 +444,7 @@ contract('ModuleRegistry', accounts => { await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, {from: account_polymath}); await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, {from: account_polymath}); let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type, permissionManagerKey, "module doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], permissionManagerKey, "module doesn't get deployed"); }); it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower", async() => { diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 92e9e3a46..590e961a3 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -259,7 +259,7 @@ contract('PercentageTransferManager', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -268,7 +268,7 @@ contract('PercentageTransferManager', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -347,7 +347,7 @@ contract('PercentageTransferManager', accounts => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); const tx = await I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); + assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), @@ -360,7 +360,7 @@ contract('PercentageTransferManager', accounts => { it("Should successfully attach the PercentageTransferManager with the security token", async () => { const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index ad5482b35..2f97f9747 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -239,7 +239,7 @@ contract('PreSaleSTO', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -248,7 +248,7 @@ contract('PreSaleSTO', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -271,7 +271,7 @@ contract('PreSaleSTO', accounts => { const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type, stoKey, "PreSaleSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], stoKey, "PreSaleSTO doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 69d9623ad..7c47e12a9 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -557,7 +557,7 @@ contract('SecurityTokenRegistry', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTrasnferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey, `Should be equal to the ${transferManagerKey}`); + assert.equal(log.args._types[0].toNumber(), transferManagerKey, `Should be equal to the ${transferManagerKey}`); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -620,7 +620,7 @@ contract('SecurityTokenRegistry', accounts => { const log = await promisifyLogWatch(I_SecurityToken002.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 79270063b..e95f6897c 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -363,12 +363,12 @@ contract('USDTieredSTO', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), TMKEY); + assert.equal(log.args._types[0].toNumber(), TMKEY); assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(TMKEY, 0); + let moduleData = (await I_SecurityToken.getModulesByType(TMKEY))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -401,7 +401,7 @@ contract('USDTieredSTO', accounts => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); @@ -447,7 +447,7 @@ contract('USDTieredSTO', accounts => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); @@ -493,7 +493,7 @@ contract('USDTieredSTO', accounts => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); }); @@ -523,7 +523,7 @@ contract('USDTieredSTO', accounts => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); }); diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index cd00ccb8d..96015926d 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -336,12 +336,12 @@ contract('USDTieredSTO Sim', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), TMKEY); + assert.equal(log.args._types[0].toNumber(), TMKEY); assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(TMKEY, 0); + let moduleData = (await I_SecurityToken.getModulesByType(TMKEY))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -379,7 +379,7 @@ contract('USDTieredSTO Sim', accounts => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); diff --git a/test/r_concurrent_STO.js b/test/r_concurrent_STO.js index f01a36436..569534cad 100644 --- a/test/r_concurrent_STO.js +++ b/test/r_concurrent_STO.js @@ -247,12 +247,12 @@ contract('Concurrent STO', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -300,21 +300,21 @@ contract('Concurrent STO', accounts => { case 0: // Capped STO let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { from: account_issuer }); - assert.equal(tx1.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(tx1.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); assert.equal(web3.utils.hexToString(tx1.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); I_STO_Array.push(CappedSTO.at(tx1.logs[3].args._module)); break; case 1: // Dummy STO let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { from: account_issuer }); - assert.equal(tx2.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(tx2.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); assert.equal(web3.utils.hexToString(tx2.logs[3].args._name),"DummySTO",`Wrong STO module added at index ${STOIndex}`); I_STO_Array.push(DummySTO.at(tx2.logs[3].args._module)); break; case 2: // Pre Sale STO let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { from: account_issuer }); - assert.equal(tx3.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(tx3.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); assert.equal(web3.utils.hexToString(tx3.logs[3].args._name),"PreSaleSTO",`Wrong STO module added at index ${STOIndex}`); I_STO_Array.push(PreSaleSTO.at(tx3.logs[3].args._module)); break; diff --git a/test/s_v130_to_v140_upgrade.js b/test/s_v130_to_v140_upgrade.js index 4db50ca9f..f4dee4bf2 100644 --- a/test/s_v130_to_v140_upgrade.js +++ b/test/s_v130_to_v140_upgrade.js @@ -490,7 +490,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken1.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER1 }); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); I_USDTieredSTO = USDTieredSTO.at(tx.logs[2].args._module); }); @@ -517,14 +517,14 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [fundRaiseType], fundsReceiver]); let tx = await I_SecurityToken2.addModule(I_UpgradedCappedSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER2 }); - assert.equal(tx.logs[2].args._type, STOKEY, "CappedSTO doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0], STOKEY, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"CappedSTO","CappedSTOFactory module was not added"); }); // Attach ManualApprovalTransferManager module for TOK2 it("Should successfully attach the ManualApprovalTransferManagerFactory with the second token", async () => { const tx = await I_SecurityToken2.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: ISSUER2 }); - assert.equal(tx.logs[2].args._type.toNumber(), TMKEY, "ManualApprovalTransferManagerFactory doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), TMKEY, "ManualApprovalTransferManagerFactory doesn't get deployed"); assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManagerFactory module was not added"); I_ManualApprovalTransferManagerFactory = ManualApprovalTransferManagerFactory.at(tx.logs[2].args._module); }); diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 2666f7158..7032337f7 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -196,7 +196,7 @@ contract ("SecurityTokenRegistryProxy", accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); }); }) diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 634eb31e2..082c49d28 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -237,7 +237,7 @@ contract('TrackedRedemption', accounts => { const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); + assert.equal(log.args._types[0].toNumber(), 2); assert.equal( web3.utils.toAscii(log.args._name) .replace(/\u0000/g, ''), @@ -246,14 +246,14 @@ contract('TrackedRedemption', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the TrackedRedemption with the security token", async () => { const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), From 527869613f1c15c565eb0cfb15c5a51c5df1ee98 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 22:59:20 +0100 Subject: [PATCH 029/142] More fixes --- contracts/tokens/SecurityToken.sol | 8 ++------ test/b_capped_sto.js | 6 +++--- test/d_count_transfer_manager.js | 2 +- test/e_erc20_dividends.js | 2 +- test/f_ether_dividends.js | 2 +- test/g_general_permission_manager.js | 2 +- test/h_general_transfer_manager.js | 4 ++-- test/j_manual_approval_transfer_manager.js | 2 +- test/l_percentage_transfer_manager.js | 2 +- test/m_presale_sto.js | 2 +- test/p_usd_tiered_sto.js | 2 +- test/v_tracked_redemptions.js | 2 +- 12 files changed, 16 insertions(+), 20 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 0ec644503..e0a0cdb18 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -468,7 +468,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function _adjustTotalSupplyCheckpoints() internal { TokenLib.adjustCheckpoints(checkpointTotalSupply, totalSupply(), currentCheckpointId); - /* _adjustCheckpoints(checkpointTotalSupply, totalSupply()); */ } /** @@ -477,7 +476,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function _adjustBalanceCheckpoints(address _investor) internal { TokenLib.adjustCheckpoints(checkpointBalances[_investor], balanceOf(_investor), currentCheckpointId); - /* _adjustCheckpoints(checkpointBalances[_investor], balanceOf(_investor)); */ } /** @@ -583,9 +581,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function mint(address _investor, uint256 _value) public onlyModuleOrOwner(MINT_KEY) checkGranularity(_value) isMintingAllowed() returns (bool success) { require(_investor != address(0), "Investor is 0"); - _adjustInvestorCount(address(0), _investor, _value); - require(_verifyTransfer(address(0), _investor, _value, true), "Transfer not valid"); - _adjustBalanceCheckpoints(_investor); + require(_updateTransfer(address(0), _investor, _value), "Transfer not valid"); _adjustTotalSupplyCheckpoints(); totalSupply_ = totalSupply_.add(_value); balances[_investor] = balances[_investor].add(_value); @@ -733,7 +729,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr balances[_from] = balances[_from].sub(_value); return verified; } - + /** * @notice Use by a controller to execute a foced burn * @param _from address from which to take tokens diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 795bfc843..c753d22db 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -274,7 +274,7 @@ contract('CappedSTO', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken_ETH.modules(transferManagerKey, 0); + let moduleData = (await I_SecurityToken_ETH.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -891,7 +891,7 @@ contract('CappedSTO', accounts => { }); it("POLY: Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken_POLY.modules(transferManagerKey, 0); + let moduleData = (await I_SecurityToken_POLY.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); @@ -1102,7 +1102,7 @@ contract('CappedSTO', accounts => { describe("Test cases for the CappedSTOFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_CappedSTOFactory.setupCost.call()).toNumber(), cappedSTOSetupCost); - assert.equal(await I_CappedSTOFactory.getTypes.call(0),3); + assert.equal((await I_CappedSTOFactory.getTypes.call())[0],3); assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), "CappedSTO", "Wrong Module added"); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index c334e0d0d..164538f50 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -477,7 +477,7 @@ contract('CountTransferManager', accounts => { describe("Test cases for the factory", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_CountTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_CountTransferManagerFactory.getTypes.call(0),2); + assert.equal((await I_CountTransferManagerFactory.getTypes.call())[0],2); assert.equal(web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()) .replace(/\u0000/g, ''), "CountTransferManager", diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index e21073f06..9f8f71984 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -938,7 +938,7 @@ contract('ERC20DividendCheckpoint', accounts => { describe("Test cases for the ERC20DividendCheckpointFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_ERC20DividendCheckpointFactory.getTypes.call(0), 4); + assert.equal((await I_ERC20DividendCheckpointFactory.getTypes.call())[0], 4); assert.equal(web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()) .replace(/\u0000/g, ''), "ERC20DividendCheckpoint", diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index c02698e87..b65a8f7c1 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -958,7 +958,7 @@ contract('EtherDividendCheckpoint', accounts => { describe("Test cases for the EtherDividendCheckpointFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_EtherDividendCheckpointFactory.getTypes.call(0), 4); + assert.equal((await I_EtherDividendCheckpointFactory.getTypes.call())[0], 4); assert.equal(web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()) .replace(/\u0000/g, ''), "EtherDividendCheckpoint", diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index b59ad25f1..32b501565 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -398,7 +398,7 @@ contract('GeneralPermissionManager', accounts => { describe("General Permission Manager Factory test cases", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); - assert.equal(await I_GeneralPermissionManagerFactory.getTypes.call(0),1); + assert.equal((await I_GeneralPermissionManagerFactory.getTypes.call())[0],1); assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) .replace(/\u0000/g, ''), "GeneralPermissionManager", diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 0c4deb6c8..232f7c1d2 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -791,7 +791,7 @@ contract('GeneralTransferManager', accounts => { it("Should get the exact details of the factory", async() => { assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_GeneralTransferManagerFactory.getTypes.call(0),2); + assert.equal((await I_GeneralTransferManagerFactory.getTypes.call())[0],2); assert.equal(web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()) .replace(/\u0000/g, ''), "GeneralTransferManager", @@ -817,7 +817,7 @@ contract('GeneralTransferManager', accounts => { describe("Dummy STO Factory test cases", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_DummySTOFactory.setupCost.call(),0); - assert.equal(await I_DummySTOFactory.getTypes.call(0),3); + assert.equal((await I_DummySTOFactory.getTypes.call())[0],3); assert.equal(web3.utils.toAscii(await I_DummySTOFactory.getName.call()) .replace(/\u0000/g, ''), "DummySTO", diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 08a69c318..cc6471e8a 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -691,7 +691,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Should get the exact details of the factory", async() => { assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_ManualApprovalTransferManagerFactory.getTypes.call(0),2); + assert.equal((await I_ManualApprovalTransferManagerFactory.getTypes.call())[0],2); let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); assert.equal(name,"ManualApprovalTransferManager","Wrong Module added"); let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 590e961a3..a3af87a97 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -459,7 +459,7 @@ contract('PercentageTransferManager', accounts => { it("Should get the exact details of the factory", async() => { assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_PercentageTransferManagerFactory.getTypes.call(0),2); + assert.equal((await I_PercentageTransferManagerFactory.getTypes.call())[0],2); assert.equal(web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()) .replace(/\u0000/g, ''), "PercentageTransferManager", diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index 2f97f9747..81ed48fd7 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -455,7 +455,7 @@ contract('PreSaleSTO', accounts => { describe("Test cases for the PresaleSTOFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal(await I_PreSaleSTOFactory.setupCost.call(),0); - assert.equal(await I_PreSaleSTOFactory.getTypes.call(0),3); + assert.equal((await I_PreSaleSTOFactory.getTypes.call())[0],3); assert.equal(web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()) .replace(/\u0000/g, ''), "PreSaleSTO", diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index e95f6897c..20656b0bc 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -3493,7 +3493,7 @@ contract('USDTieredSTO', accounts => { describe("Test cases for the USDTieredSTOFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_USDTieredSTOFactory.setupCost.call()).toNumber(), STOSetupCost); - assert.equal(await I_USDTieredSTOFactory.getTypes.call(0),3); + assert.equal((await I_USDTieredSTOFactory.getTypes.call())[0],3); assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), "USDTieredSTO", "Wrong Module added"); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 082c49d28..4330616ea 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -354,7 +354,7 @@ contract('TrackedRedemption', accounts => { describe("Test cases for the TrackedRedemptionFactory", async() => { it("should get the exact details of the factory", async() => { assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_TrackedRedemptionFactory.getTypes.call(0), 5); + assert.equal((await I_TrackedRedemptionFactory.getTypes.call())[0], 5); assert.equal(web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()) .replace(/\u0000/g, ''), "TrackedRedemption", From 3b0f0be4b71d3288b22cabd172fb9ed211672759 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 23:18:40 +0100 Subject: [PATCH 030/142] Remove kludge --- .../modules/TransferManager/GeneralTransferManagerFactory.sol | 3 +-- contracts/tokens/SecurityToken.sol | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol index 8b8dd8790..60e85f8f4 100644 --- a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol @@ -41,9 +41,8 @@ contract GeneralTransferManagerFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - uint8[] memory res = new uint8[](2); + uint8[] memory res = new uint8[](1); res[0] = 2; - res[1] = 3; return res; } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index e0a0cdb18..9f232463b 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -547,8 +547,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } // If no unarchived modules, return true by default return unarchived ? (isForceValid ? true : (isInvalid ? false : isValid)) : true; - } - return false; + } + return false; } /** From b91c14ef5693b3d871800ebd9290836ea6c6d743 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Wed, 3 Oct 2018 23:32:15 +0100 Subject: [PATCH 031/142] Fix some more tests --- contracts/mocks/MockFactory.sol | 3 +-- contracts/modules/Checkpoint/DividendCheckpoint.sol | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/mocks/MockFactory.sol b/contracts/mocks/MockFactory.sol index ba1f38083..144db6b15 100644 --- a/contracts/mocks/MockFactory.sol +++ b/contracts/mocks/MockFactory.sol @@ -41,8 +41,7 @@ contract MockFactory is ModuleFactory { * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - uint8[] memory res = new uint8[](1); - res[0] = 0; + uint8[] memory res = new uint8[](0); return res; } diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 425de3e90..006ec1bde 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -134,7 +134,7 @@ contract DividendCheckpoint is ICheckpoint, Module { address[] memory investors = ISecurityToken(securityToken).getInvestors(); uint256 numberInvestors = investors.length; for (uint256 i = _start; i < Math.min256(numberInvestors, _start.add(_iterations)); i++) { - address payee = ISecurityToken(securityToken).investors(i); + address payee = investors[i]; if ((!dividend.claimed[payee]) && (!dividend.dividendExcluded[payee])) { _payDividend(payee, dividend, _dividendIndex); } From 476e535f5a153785a785b123875802bfaeccc31e Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 09:25:43 +0530 Subject: [PATCH 032/142] STR test cases updated --- test/n_security_token_registry.js | 606 ++++++++++-------------------- 1 file changed, 193 insertions(+), 413 deletions(-) diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 69d9623ad..2639e098d 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -1,7 +1,8 @@ import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; +import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); @@ -275,67 +276,41 @@ contract('SecurityTokenRegistry', accounts => { }); it("Can't call the intialize function again", async() => { - let errorThrown = false; - try { - await I_STRProxied.initialize(I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath); - } catch(error) { - console.log(` tx revert -> Can't call the intialize function again`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.initialize(I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath), + "tx revert -> Can't call the intialize function again" + ); }) it("Should fail to register ticker if tickerRegFee not approved", async() => { - let errorThrown = false; - try { - let tx = await I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }); - } catch(error) { - console.log(` tx revert -> POLY allowance not provided for registration fee`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }), + "tx revert -> POLY allowance not provided for registration fee" + ); }); it("Should fail to register ticker if owner is 0x", async() => { - let errorThrown = false; - try { - await I_PolyToken.getTokens(initRegFee, account_temp); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); - let tx = await I_STRProxied.registerTicker("0x0000000000000000000000000000000000000000", symbol, name, { from: account_temp }); - } catch(error) { - console.log(` tx revert -> owner should not be 0x`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await I_PolyToken.getTokens(initRegFee, account_temp); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); + + catchRevert( + I_STRProxied.registerTicker("0x0000000000000000000000000000000000000000", symbol, name, { from: account_temp }), + "tx revert -> owner should not be 0x" + ); }); it("Should fail to register ticker due to the symbol length is 0", async() => { - let errorThrown = false; - try { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); - let tx = await I_STRProxied.registerTicker(account_temp, "", name, { from: account_temp }); - } catch(error) { - console.log(` tx revert -> Symbol Length is 0`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.registerTicker(account_temp, "", name, { from: account_temp }), + "tx revert -> Symbol Length is 0" + ); }); it("Should fail to register ticker due to the symbol length is greater than 10", async() => { - let errorThrown = false; - try { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); - let tx = await I_STRProxied.registerTicker(account_temp, "POLYMATHNET", name, { from: account_temp }); - } catch(error) { - console.log(` tx revert -> Symbol Length is greater than 10`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.registerTicker(account_temp, "POLYMATHNET", name, { from: account_temp }), + "tx revert -> Symbol Length is greater than 10" + ); }); it("Should register the ticker before the generation of the security token", async () => { @@ -347,18 +322,12 @@ contract('SecurityTokenRegistry', accounts => { it("Should fail to register same symbol again", async() => { // Give POLY to token issuer await I_PolyToken.getTokens(initRegFee, token_owner); - + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); // Call registration function - let errorThrown = false; - try { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Symbol is already alloted to someone else`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }), + "tx revert -> Symbol is already alloted to someone else" + ); }); it("Should successfully register pre registerd ticker if expiry is reached", async() => { @@ -370,29 +339,20 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to register ticker if registration is paused", async() => { - let errorThrown = false; - try { - await I_STRProxied.pause({ from: account_polymath}); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Registration is paused`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await I_STRProxied.pause({ from: account_polymath}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + + catchRevert( + I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }), + "tx revert -> Registration is paused" + ); }); it("Should fail to pause if already paused", async() => { - let errorThrown = false; - try { - await I_STRProxied.pause({ from: account_polymath}); - } catch(error) { - console.log(` tx revert -> Registration is already paused`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.pause({ from: account_polymath}), + "tx revert -> Registration is already paused" + ); }); it("Should successfully register ticker if registration is unpaused", async() => { @@ -404,30 +364,20 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to unpause if already unpaused", async() => { - let errorThrown = false; - try { - await I_STRProxied.unpause({ from: account_polymath}); - } catch(error) { - console.log(` tx revert -> Registration is already unpaused`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.unpause({ from: account_polymath}), + "tx revert -> Registration is already unpaused" + ); }); }); describe("Test cases for the expiry limit", async() => { it("Should fail to set the expiry limit because msg.sender is not owner", async() => { - let errorThrown = false; - try { - let tx = await I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_temp}); - } catch(error) { - console.log(` tx revert -> msg.sender is not owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_temp}), + "tx revert -> msg.sender is not owner" + ); }); it("Should successfully set the expiry limit", async() => { @@ -440,15 +390,10 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to set the expiry limit because new expiry limit is lesser than one day", async() => { - let errorThrown = false; - try { - let tx = await I_STRProxied.changeExpiryLimit(duration.seconds(5000), {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> New expiry limit is lesser than one day`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeExpiryLimit(duration.seconds(5000), {from: account_polymath}), + "tx revert -> New expiry limit is lesser than one day" + ) }); }); @@ -482,67 +427,45 @@ contract('SecurityTokenRegistry', accounts => { }) it("Should fail to generate new security token if fee not provided", async() => { - let errorThrown = false; await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner}); - try { - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> POLY allowance not provided for registration fee`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> POLY allowance not provided for registration fee" + ); }); it("Should fail to generate token if registration is paused", async() => { - let errorThrown = false; await I_STRProxied.pause({ from: account_polymath}); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - try { - await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Registration is paused`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> Registration is paused" + ); }); it("Should fail to generate the securityToken -- Because ticker length is 0", async() => { - let errorThrown = false; await I_STRProxied.unpause({ from: account_polymath}); - try { - await I_STRProxied.generateSecurityToken(name, "", tokenDetails, false, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Zero ticker length is not allowed`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + + catchRevert( + I_STRProxied.generateSecurityToken(name, "", tokenDetails, false, { from: token_owner }), + "tx revert -> Zero ticker length is not allowed" + ) }) it("Should fail to generate the securityToken -- Because name length is 0", async() => { - let errorThrown = false; - try { - await I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> 0 name length is not allowed`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> 0 name length is not allowed" + ); }) it("Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker", async() => { - let errorThrown = false; - try { - await I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp }); - } catch(error) { - console.log(` tx revert -> Because msg.sender is not the rightful owner of the ticker`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp }), + "tx revert -> Because msg.sender is not the rightful owner of the ticker" + ) }) it("Should generate the new security token with the same symbol as registered above", async () => { @@ -566,15 +489,10 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to generate the SecurityToken when token is already deployed with the same symbol", async() => { - let errorThrown = false; - try { - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Because ticker is already in use`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> Because ticker is already in use" + ); }) }); @@ -642,16 +560,12 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to upgrade the logic contract of the STRProxy -- bad owner", async() => { - let errorThrown = false; await I_STRProxied.pause({from: account_polymath}); - try { - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_temp}); - } catch(error) { - console.log(` tx revert -> bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + + catchRevert( + I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_temp}), + "tx revert -> bad owner" + ) }) it("Should upgrade the logic contract into the STRProxy", async() =>{ @@ -676,63 +590,38 @@ contract('SecurityTokenRegistry', accounts => { describe("Generate custom tokens", async() => { it("Should fail if msg.sender is not polymath", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_delegate}); - } catch(error) { - console.log(` tx revert -> msg.sender is not polymath account`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_delegate}), + "tx revert -> msg.sender is not polymath account" + ); }); it("Should fail to generate the custom security token -- name should not be 0 length ", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifySecurityToken("", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> name should not be 0 length `.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifySecurityToken("", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}), + "tx revert -> name should not be 0 length" + ); }); it("Should fail if ST address is 0 address", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", latestTime(), {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> Security token address is 0`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", latestTime(), {from: account_polymath}), + "tx revert -> Security token address is 0" + ); }); it("Should fail if symbol length is 0", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifySecurityToken("", "", account_temp, dummy_token, "I am custom ST",latestTime(), {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> zero length of the symbol is not allowed`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifySecurityToken("", "", account_temp, dummy_token, "I am custom ST",latestTime(), {from: account_polymath}), + "tx revert -> zero length of the symbol is not allowed" + ); }); it("Should fail to generate the custom ST -- deployedAt param is 0", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, "I am custom ST", 0, {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> because deployedAt param is 0`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, "I am custom ST", 0, {from: account_polymath}), + "tx revert -> because deployedAt param is 0" + ); }); it("Should successfully generate custom token", async() => { @@ -783,63 +672,38 @@ contract('SecurityTokenRegistry', accounts => { describe("Test case for modifyTicker", async() => { it("Should add the custom ticker --failed because of bad owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_temp}) - } catch(error) { - console.log(` tx revert -> failed beacause ticker length should not be 0`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_temp}), + "tx revert -> failed beacause of bad owner0" + ); }) it("Should add the custom ticker --fail ticker length should not be 0", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifyTicker(token_owner, "", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_polymath}) - } catch(error) { - console.log(` tx revert -> failed beacause ticker length should not be 0`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifyTicker(token_owner, "", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_polymath}), + "tx revert -> failed beacause ticker length should not be 0" + ); }) it("Should add the custom ticker --failed because time should not be 0", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", 0, (latestTime() + duration.days(10)), false, {from: account_polymath}) - } catch(error) { - console.log(` tx revert -> failed because time should not be 0`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", 0, (latestTime() + duration.days(10)), false, {from: account_polymath}), + "tx revert -> failed because time should not be 0" + ); }) it("Should add the custom ticker --failed because registeration date is greater than the expiryDate", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() - duration.minutes(10)), false, {from: account_polymath}) - } catch(error) { - console.log(` tx revert -> failed because registeration date is greater than the expiryDate`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() - duration.minutes(10)), false, {from: account_polymath}), + "tx revert -> failed because registeration date is greater than the expiryDate" + ); }) it("Should add the custom ticker --failed because owner should not be 0x", async() => { - let errorThrown = false; - try { - await I_STRProxied.modifyTicker("0x000000000000000000000000000000000000000000", "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}) - } catch(error) { - console.log(` tx revert -> failed because owner should not be 0x`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.modifyTicker("0x000000000000000000000000000000000000000000", "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}), + "tx revert -> failed because owner should not be 0x" + ); }) it("Should add the new custom ticker", async() => { @@ -858,40 +722,26 @@ contract('SecurityTokenRegistry', accounts => { describe("Test cases for the transferTickerOwnership()", async() => { it("Should able to transfer the ticker ownership -- failed because token is not deployed having the same ticker", async() => { - let errorThrown = false; - try { - await I_STRProxied.transferTickerOwnership(account_issuer, "ETH", {from: account_temp}); - } catch(error) { - console.log(` tx revert -> failed because token is not deployed having the same ticker`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.transferTickerOwnership(account_issuer, "ETH", {from: account_temp}), + "tx revert -> failed because token is not deployed having the same ticker" + ) }) it("Should able to transfer the ticker ownership -- failed because new owner is 0x", async() => { let errorThrown = false; await I_SecurityToken002.transferOwnership(account_temp, {from: token_owner}); - try { - await I_STRProxied.transferTickerOwnership("0x00000000000000000000000000000000000000000", symbol2, {from: token_owner}); - } catch(error) { - console.log(` tx revert -> failed because new owner is 0x`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.transferTickerOwnership("0x00000000000000000000000000000000000000000", symbol2, {from: token_owner}), + "tx revert -> failed because new owner is 0x" + ) }) it("Should able to transfer the ticker ownership -- failed because ticker is of zero length", async() => { - let errorThrown = false; - try { - await I_STRProxied.transferTickerOwnership(account_temp, "", {from: token_owner}); - } catch(error) { - console.log(` tx revert -> failed because ticker is of zero length`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.transferTickerOwnership(account_temp, "", {from: token_owner}), + "tx revert -> failed because ticker is of zero length" + ); }) it("Should able to transfer the ticker ownership", async() => { @@ -906,27 +756,17 @@ contract('SecurityTokenRegistry', accounts => { describe("Test case for the changeSecurityLaunchFee()", async() => { it("Should able to change the STLaunchFee-- failed because of bad owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_temp}); - } catch(error) { - console.log(` tx revert -> failed because of bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_temp}), + "tx revert -> failed because of bad owner" + ); }); it("Should able to change the STLaunchFee-- failed because of putting the same fee", async() => { - let errorThrown = false; - try { - await I_STRProxied.changeSecurityLaunchFee(initRegFee, {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> failed because of putting the same fee`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeSecurityLaunchFee(initRegFee, {from: account_polymath}), + "tx revert -> failed because of putting the same fee" + ) }); it("Should able to change the STLaunchFee", async() => { @@ -941,27 +781,17 @@ contract('SecurityTokenRegistry', accounts => { describe("Test cases for the changeExpiryLimit()", async() => { it("Should able to change the ExpiryLimit-- failed because of bad owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.changeExpiryLimit(duration.days(15), {from: account_temp}); - } catch(error) { - console.log(` tx revert -> failed because of bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeExpiryLimit(duration.days(15), {from: account_temp}), + "tx revert -> failed because of bad owner" + ) }); it("Should able to change the ExpiryLimit-- failed because expirylimit is less than 1 day", async() => { - let errorThrown = false; - try { - await I_STRProxied.changeExpiryLimit(duration.minutes(50), {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> failed because expirylimit is less than 1 day`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeExpiryLimit(duration.minutes(50), {from: account_polymath}), + "tx revert -> failed because expirylimit is less than 1 day" + ); }); it("Should able to change the ExpiryLimit", async() => { @@ -975,27 +805,17 @@ contract('SecurityTokenRegistry', accounts => { describe("Test cases for the changeTickerRegistrationFee()", async() => { it("Should able to change the TickerRegFee-- failed because of bad owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("500"), {from: account_temp}); - } catch(error) { - console.log(` tx revert -> failed because of bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("500"), {from: account_temp}), + "tx revert -> failed because of bad owner" + ) }); it("Should able to change the TickerRegFee-- failed because of putting the same fee", async() => { - let errorThrown = false; - try { - await I_STRProxied.changeTickerRegistrationFee(initRegFee, {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> failed because of putting the same fee`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.changeTickerRegistrationFee(initRegFee, {from: account_polymath}), + "tx revert -> failed because of putting the same fee" + ); }); it("Should able to change the TickerRegFee", async() => { @@ -1006,16 +826,11 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to register the ticker with the old fee", async () => { - let errorThrown = false; await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - try { - await I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }); - } catch(error) { - console.log(` tx revert -> failed because of ticker registeration fee gets change`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }), + "tx revert -> failed because of ticker registeration fee gets change" + ); }) it("Should register the ticker with the new fee", async() => { @@ -1027,16 +842,11 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to launch the securityToken with the old launch fee", async() => { - let errorThrown = false; await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - try { - await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> failed because of old launch fee`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }), + "tx revert -> failed because of old launch fee" + ) }) it("Should launch the the securityToken", async() => { @@ -1051,27 +861,17 @@ contract('SecurityTokenRegistry', accounts => { describe("Test case for the update poly token", async() => { it("Should change the polytoken address -- failed because of bad owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_temp}); - } catch(error) { - console.log(` tx revert -> failed because of bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_temp}), + "tx revert -> failed because of bad owner" + ); }) it("Should change the polytoken address -- failed because of 0x address", async() => { - let errorThrown = false; - try { - await I_STRProxied.updatePolyTokenAddress("0x0000000000000000000000000000000000000000000", {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> failed because 0x address`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.updatePolyTokenAddress("0x0000000000000000000000000000000000000000000", {from: account_polymath}), + "tx revert -> failed because 0x address" + ); }) it("Should successfully change the polytoken address", async() => { @@ -1108,27 +908,17 @@ contract('SecurityTokenRegistry', accounts => { describe("Test case for the Removing the ticker", async() => { it("Should remove the ticker from the polymath ecosystem -- bad owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.removeTicker(symbol2, {from: account_investor1}); - } catch(error) { - console.log(` tx revert -> failed because msg.sender should be account_polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.removeTicker(symbol2, {from: account_investor1}), + "tx revert -> failed because msg.sender should be account_polymath" + ) }) it("Should remove the ticker from the polymath ecosystem -- fail because ticker doesn't exist in the ecosystem", async() => { - let errorThrown = false; - try { - await I_STRProxied.removeTicker("HOLA", {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> failed because ticker doesn't exist in the polymath ecosystem`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.removeTicker("HOLA", {from: account_polymath}), + "tx revert -> failed because ticker doesn't exist in the polymath ecosystem" + ) }) it("Should successfully remove the ticker from the polymath ecosystem", async() => { @@ -1206,15 +996,10 @@ contract('SecurityTokenRegistry', accounts => { describe("Test cases for pausing the contract", async() => { it("Should fail to pause if msg.sender is not owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.pause({ from: account_temp }); - } catch(error) { - console.log(` tx revert -> msg.sender should be account_polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.pause({ from: account_temp }), + "tx revert -> msg.sender should be account_polymath" + ) }); it("Should successfully pause the contract", async() => { @@ -1224,15 +1009,10 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should fail to unpause if msg.sender is not owner", async() => { - let errorThrown = false; - try { - await I_STRProxied.unpause({ from: account_temp }); - } catch(error) { - console.log(` tx revert -> msg.sender should be account_polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + catchRevert( + I_STRProxied.unpause({ from: account_temp }), + "tx revert -> msg.sender should be account_polymath" + ) }); it("Should successfully unpause the contract", async() => { From b37b6052df8190070c4f318c7d452d24ac5712fc Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 11:30:07 +0530 Subject: [PATCH 033/142] move investors data and logic into the library --- contracts/libraries/TokenLib.sol | 51 ++++++++++++++++++++++++++++++ contracts/tokens/SecurityToken.sol | 43 +++++++------------------ migrations/2_deploy_contracts.js | 34 -------------------- test/o_security_token.js | 12 +++---- 4 files changed, 68 insertions(+), 72 deletions(-) diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index 8fa281d26..24c09f81c 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -1,9 +1,12 @@ pragma solidity ^0.4.24; import "../modules/PermissionManager/IPermissionManager.sol"; +import "./KindMath.sol"; library TokenLib { + using KindMath for uint256; + // Struct for module data struct ModuleData { bytes32 name; @@ -22,6 +25,15 @@ library TokenLib { uint256 value; } + struct InvestorDataStorage { + // List of investors (may not be pruned to remove old investors with current zero balances) + mapping (address => bool) investorListed; + // List of token holders + address[] investors; + // Total number of non-zero token holders + uint256 investorCount; + } + // Emit when Module get archived from the securityToken event ModuleArchived(uint8[] _types, address _module, uint256 _timestamp); // Emit when Module get unarchived from the securityToken @@ -148,5 +160,44 @@ library TokenLib { ); } + /** + * @notice keeps track of the number of non-zero token holders + * @param _from sender of transfer + * @param _to receiver of transfer + * @param _value value of transfer + */ + function adjustInvestorCount(InvestorDataStorage storage _investors, address _from, address _to, uint256 _value, uint256 _balanceTo, uint256 _balanceFrom) public { + if ((_value == 0) || (_from == _to)) { + return; + } + // Check whether receiver is a new token holder + if ((_balanceTo == 0) && (_to != address(0))) { + _investors.investorCount = (_investors.investorCount).add(1); + } + // Check whether sender is moving all of their tokens + if (_value == _balanceFrom) { + _investors.investorCount = (_investors.investorCount).sub(1); + } + //Also adjust investor list + if (!_investors.investorListed[_to] && (_to != address(0))) { + _investors.investors.push(_to); + _investors.investorListed[_to] = true; + } + + } + + /** + * @notice removes addresses with zero balances from the investors list + * @param _index Index in investor list at which to start removing zero balances + * NB - pruning this list will mean you may not be able to iterate over investors on-chain as of a historical checkpoint + */ + function pruneInvestors(InvestorDataStorage storage _investorData, uint256 _index) public { + _investorData.investorListed[_investorData.investors[_index]] = false; + _investorData.investors[_index] = _investorData.investors[_investorData.investors.length - 1]; + _investorData.investors.length--; + } + + + } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 9f232463b..27564e0e7 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -27,6 +27,8 @@ import "../libraries/TokenLib.sol"; contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, RegistryUpdater { using SafeMath for uint256; + TokenLib.InvestorDataStorage investorData; + // Use to hold the version struct SemanticVersion { uint8 major; @@ -50,12 +52,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // Value of current checkpoint uint256 public currentCheckpointId; - // Total number of non-zero token holders - uint256 public investorCount; - - // List of token holders - address[] investors; - // Use to temporarily halt all transactions bool public transfersFrozen; @@ -86,9 +82,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // Times at which each checkpoint was created uint256[] checkpointTimes; - // List of investors (may not be pruned to remove old investors with current zero balances) - mapping (address => bool) investorListed; - // Emit at the time when module get added event ModuleAdded( uint8[] _types, @@ -401,23 +394,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _value value of transfer */ function _adjustInvestorCount(address _from, address _to, uint256 _value) internal { - if ((_value == 0) || (_from == _to)) { - return; - } - // Check whether receiver is a new token holder - if ((balanceOf(_to) == 0) && (_to != address(0))) { - investorCount = investorCount.add(1); - } - // Check whether sender is moving all of their tokens - if (_value == balanceOf(_from)) { - investorCount = investorCount.sub(1); - } - //Also adjust investor list - if (!investorListed[_to] && (_to != address(0))) { - investors.push(_to); - investorListed[_to] = true; - } - + TokenLib.adjustInvestorCount(investorData, _from, _to, _value, balanceOf(_to), balanceOf(_from)); } /** @@ -427,11 +404,9 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * NB - pruning this list will mean you may not be able to iterate over investors on-chain as of a historical checkpoint */ function pruneInvestors(uint256 _start, uint256 _iters) external onlyOwner { - for (uint256 i = _start; i < Math.min256(_start.add(_iters), investors.length); i++) { - if ((i < investors.length) && (balanceOf(investors[i]) == 0)) { - investorListed[investors[i]] = false; - investors[i] = investors[investors.length - 1]; - investors.length--; + for (uint256 i = _start; i < Math.min256(_start.add(_iters), investorData.investors.length); i++) { + if ((i < investorData.investors.length) && (balanceOf(investorData.investors[i]) == 0)) { + TokenLib.pruneInvestors(investorData, i); } } } @@ -442,7 +417,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return length */ function getInvestors() external view returns(address[]) { - return investors; + return investorData.investors; + } + + function getInvestorCount() external view returns(uint256) { + return investorData.investorCount; } /** diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index fd2c27bb0..7b1feeece 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -133,40 +133,6 @@ module.exports = function (deployer, network, accounts) { }).then(() => { // Link libraries return deployer.link(TokenLib, STFactory); - // }).then(() => { - // return deployer.link(VersionUtils, SecurityTokenRegistry); - // }).then(() => { - // return deployer.link(VersionUtils, GeneralTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, GeneralPermissionManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, PercentageTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, USDTieredSTOProxyFactory); - // }).then(() => { - // return deployer.link(VersionUtils, CountTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, EtherDividendCheckpointFactory); - // }).then(() => { - // return deployer.link(VersionUtils, ERC20DividendCheckpointFactory); - // }).then(() => { - // return deployer.link(VersionUtils, ManualApprovalTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, CappedSTOFactory); - // }).then(() => { - // return deployer.link(VersionUtils, USDTieredSTOFactory); - // }).then(() => { - // return deployer.link(Util, CappedSTOFactory); - // }).then(() => { - // return deployer.link(Util, USDTieredSTOFactory); - // }).then(() => { - // return deployer.link(Util, CountTransferManagerFactory); - // }).then(() => { - // return deployer.link(Util, PercentageTransferManagerFactory); - // }).then(() => { - // return deployer.link(Util, SecurityTokenRegistry); - // }).then(() => { - // return deployer.link(Util, STFactory); }).then(() => { // A) Deploy the ModuleRegistry Contract (It contains the list of verified ModuleFactory) return deployer.deploy(ModuleRegistry, {from: PolymathAccount}); diff --git a/test/o_security_token.js b/test/o_security_token.js index 68b3d6816..b6abc9b20 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -1154,7 +1154,7 @@ contract('SecurityToken', accounts => { it("Should force burn the tokens - value too high", async ()=> { let errorThrown = false; await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); try { let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", { from: account_controller }); @@ -1168,7 +1168,7 @@ contract('SecurityToken', accounts => { it("Should force burn the tokens - wrong caller", async ()=> { let errorThrown = false; await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); try { let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: token_owner }); @@ -1181,13 +1181,13 @@ contract('SecurityToken', accounts => { }); it("Should burn the tokens", async ()=> { - let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); // console.log(currentInvestorCount.toString(), currentBalance.toString()); let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: account_controller }); // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); - let newInvestorCount = await I_SecurityToken.investorCount(); + let newInvestorCount = await I_SecurityToken.getInvestorCount.call(); // console.log(newInvestorCount.toString()); assert.equal(newInvestorCount.toNumber() + 1, currentInvestorCount.toNumber(), "Investor count drops by one"); }); @@ -1298,13 +1298,13 @@ contract('SecurityToken', accounts => { let sender = account_investor1; let receiver = account_investor2; - let start_investorCount = await I_SecurityToken.investorCount.call(); + let start_investorCount = await I_SecurityToken.getInvestorCount.call(); let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); - let end_investorCount = await I_SecurityToken.investorCount.call(); + let end_investorCount = await I_SecurityToken.getInvestorCount.call(); let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); let end_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); From 11f6e60f28b4e2f10f21c4c2ebf18c4b5ec4142d Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 11:33:19 +0530 Subject: [PATCH 034/142] minor naming fix --- contracts/libraries/TokenLib.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index 24c09f81c..691b71068 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -166,22 +166,22 @@ library TokenLib { * @param _to receiver of transfer * @param _value value of transfer */ - function adjustInvestorCount(InvestorDataStorage storage _investors, address _from, address _to, uint256 _value, uint256 _balanceTo, uint256 _balanceFrom) public { + function adjustInvestorCount(InvestorDataStorage storage _investorData, address _from, address _to, uint256 _value, uint256 _balanceTo, uint256 _balanceFrom) public { if ((_value == 0) || (_from == _to)) { return; } // Check whether receiver is a new token holder if ((_balanceTo == 0) && (_to != address(0))) { - _investors.investorCount = (_investors.investorCount).add(1); + _investorData.investorCount = (_investorData.investorCount).add(1); } // Check whether sender is moving all of their tokens if (_value == _balanceFrom) { - _investors.investorCount = (_investors.investorCount).sub(1); + _investorData.investorCount = (_investorData.investorCount).sub(1); } //Also adjust investor list - if (!_investors.investorListed[_to] && (_to != address(0))) { - _investors.investors.push(_to); - _investors.investorListed[_to] = true; + if (!_investorData.investorListed[_to] && (_to != address(0))) { + _investorData.investors.push(_to); + _investorData.investorListed[_to] = true; } } From e7a290dfd03f17ae89599b510d1e760c269eb6c0 Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 12:08:57 +0530 Subject: [PATCH 035/142] cleanup --- contracts/tokens/SecurityToken.sol | 32 ++++++++++++++-------------- migrations/2_deploy_contracts.js | 34 ------------------------------ 2 files changed, 16 insertions(+), 50 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 9f232463b..f19d392e9 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -272,22 +272,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr TokenLib.unarchiveModule(modulesToData[_module], _module); } - function _removeModuleWithIndex(uint8 _type, uint256 _index) internal { - uint256 length = modules[_type].length; - modules[_type][_index] = modules[_type][length - 1]; - modules[_type].length = length - 1; - - if ((length - 1) != _index) { - //Need to find index of _type in moduleTypes of module we are moving - uint8[] memory newTypes = modulesToData[modules[_type][_index]].moduleTypes; - for (uint256 i = 0; i < newTypes.length; i++) { - if (newTypes[i] == _type) { - modulesToData[modules[_type][_index]].moduleIndexes[i] = _index; - } - } - } - } - /** * @notice Removes a module attached to the SecurityToken * @param _module address of module to unarchive @@ -315,6 +299,22 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr delete modulesToData[_module]; } + function _removeModuleWithIndex(uint8 _type, uint256 _index) internal { + uint256 length = modules[_type].length; + modules[_type][_index] = modules[_type][length - 1]; + modules[_type].length = length - 1; + + if ((length - 1) != _index) { + //Need to find index of _type in moduleTypes of module we are moving + uint8[] memory newTypes = modulesToData[modules[_type][_index]].moduleTypes; + for (uint256 i = 0; i < newTypes.length; i++) { + if (newTypes[i] == _type) { + modulesToData[modules[_type][_index]].moduleIndexes[i] = _index; + } + } + } + } + /** * @notice Returns module list for a module type * @param _module address of the module diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index fd2c27bb0..7b1feeece 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -133,40 +133,6 @@ module.exports = function (deployer, network, accounts) { }).then(() => { // Link libraries return deployer.link(TokenLib, STFactory); - // }).then(() => { - // return deployer.link(VersionUtils, SecurityTokenRegistry); - // }).then(() => { - // return deployer.link(VersionUtils, GeneralTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, GeneralPermissionManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, PercentageTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, USDTieredSTOProxyFactory); - // }).then(() => { - // return deployer.link(VersionUtils, CountTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, EtherDividendCheckpointFactory); - // }).then(() => { - // return deployer.link(VersionUtils, ERC20DividendCheckpointFactory); - // }).then(() => { - // return deployer.link(VersionUtils, ManualApprovalTransferManagerFactory); - // }).then(() => { - // return deployer.link(VersionUtils, CappedSTOFactory); - // }).then(() => { - // return deployer.link(VersionUtils, USDTieredSTOFactory); - // }).then(() => { - // return deployer.link(Util, CappedSTOFactory); - // }).then(() => { - // return deployer.link(Util, USDTieredSTOFactory); - // }).then(() => { - // return deployer.link(Util, CountTransferManagerFactory); - // }).then(() => { - // return deployer.link(Util, PercentageTransferManagerFactory); - // }).then(() => { - // return deployer.link(Util, SecurityTokenRegistry); - // }).then(() => { - // return deployer.link(Util, STFactory); }).then(() => { // A) Deploy the ModuleRegistry Contract (It contains the list of verified ModuleFactory) return deployer.deploy(ModuleRegistry, {from: PolymathAccount}); From 2b50c164d39ef27546a15a712d418e0d2f7861be Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 12:33:37 +0530 Subject: [PATCH 036/142] add some improvements --- contracts/interfaces/ISecurityToken.sol | 5 +++++ contracts/libraries/TokenLib.sol | 6 +++++- contracts/tokens/SecurityToken.sol | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index a9c3b05a8..4cf950308 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -245,4 +245,9 @@ interface ISecurityToken { * @notice Use to get the version of the securityToken */ function getVersion() external view returns(uint8[]); + + /** + * @notice gets the investor count + */ + function getInvestorCount() external view returns(uint256) } diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index 691b71068..7aaa2e7f8 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -162,9 +162,12 @@ library TokenLib { /** * @notice keeps track of the number of non-zero token holders + * @param _investorData Date releated to investor metrics * @param _from sender of transfer * @param _to receiver of transfer * @param _value value of transfer + * @param _balanceTo balance of the _to address + * @param _balanceFrom balance of the _from address */ function adjustInvestorCount(InvestorDataStorage storage _investorData, address _from, address _to, uint256 _value, uint256 _balanceTo, uint256 _balanceFrom) public { if ((_value == 0) || (_from == _to)) { @@ -188,7 +191,8 @@ library TokenLib { /** * @notice removes addresses with zero balances from the investors list - * @param _index Index in investor list at which to start removing zero balances + * @param _investorData Date releated to investor metrics + * @param _index Index in investor list * NB - pruning this list will mean you may not be able to iterate over investors on-chain as of a historical checkpoint */ function pruneInvestors(InvestorDataStorage storage _investorData, uint256 _index) public { diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 895075941..65256a914 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -420,6 +420,9 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return investorData.investors; } + /** + * @notice gets the investor count + */ function getInvestorCount() external view returns(uint256) { return investorData.investorCount; } From d5e0a7f03fd094d1cc42169da3182b3f406d4cf2 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 4 Oct 2018 13:03:16 +0530 Subject: [PATCH 037/142] added a missing semi-colon --- contracts/interfaces/ISecurityToken.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index 4cf950308..09ffd2bb9 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -249,5 +249,5 @@ interface ISecurityToken { /** * @notice gets the investor count */ - function getInvestorCount() external view returns(uint256) + function getInvestorCount() external view returns(uint256); } From eda91dc16806baae867426f634934179420bc16d Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 4 Oct 2018 09:48:24 +0200 Subject: [PATCH 038/142] fix testing with extra module attached --- test/g_general_permission_manager.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index f7d3523ad..84dd342af 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -428,11 +428,15 @@ contract('GeneralPermissionManager', accounts => { assert.equal(await I_GeneralPermissionManager.isDelegate.call(account_delegate), true); }); - //ideally need to test with another module attached + it("Should provide the permission in bulk", async() => { await I_GeneralPermissionManager.addDelegate(account_delegate3, delegateDetails, { from: token_owner}); - let tx = await I_GeneralPermissionManager.changePermissionBulk(account_delegate3, [I_GeneralTransferManager.address], ["WHITELIST"], {from: token_owner}); + + let tx = await I_GeneralPermissionManager.changePermissionBulk(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], ["WHITELIST","CHANGE_PERMISSION"], {from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate3); + + assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate3, I_GeneralTransferManager.address, "WHITELIST")); + assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate3, I_GeneralPermissionManager.address, "CHANGE_PERMISSION")); }); @@ -441,21 +445,20 @@ contract('GeneralPermissionManager', accounts => { await I_GeneralPermissionManager.changePermission(account_delegate2, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); let tx = await I_GeneralPermissionManager.getAllDelegatesWithPerm.call(I_GeneralTransferManager.address, "WHITELIST"); - console.log(tx); + // console.log(tx); assert.equal(tx.length, 3); assert.equal(tx[0], account_delegate); assert.equal(tx[1], account_delegate2); }); - //ideally need to test with another module attached it("Should return all modules and all permission", async() => { - let tx = await I_GeneralPermissionManager.getAllModulesAndPerms.call(account_delegate, [2], I_SecurityToken.address); - - console.log (tx); - + let tx = await I_GeneralPermissionManager.getAllModulesAndPerms.call(account_delegate3, [2,1], I_SecurityToken.address); + // console.log (tx); assert.equal(tx[0][0], I_GeneralTransferManager.address); assert.equal(tx[1][0], "0x57484954454c4953540000000000000000000000000000000000000000000000"); + assert.equal(tx[0][1], I_GeneralPermissionManager.address); + assert.equal(tx[1][1], "0x4348414e47455f5045524d495353494f4e000000000000000000000000000000"); }); From 00654ea53951a37cab1311d5f586255ce00dde02 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 4 Oct 2018 15:44:03 +0530 Subject: [PATCH 039/142] Removed mocks from coverage --- .solcover.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.solcover.js b/.solcover.js index 32cb416b2..17939eeff 100644 --- a/.solcover.js +++ b/.solcover.js @@ -4,5 +4,5 @@ module.exports = { copyPackages: ['openzeppelin-solidity'], testCommand: 'node ../node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` --network coverage', deepSkip: true, - skipFiles: ['external', 'flat'] + skipFiles: ['external', 'flat', 'mocks'] }; From 52f475dc90b023c3544777883bf6aebfd35fba6b Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 4 Oct 2018 15:44:23 +0530 Subject: [PATCH 040/142] Burn module test case --- test/v_tracked_redemptions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 95f3303ae..4aa6c2e1e 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -355,6 +355,7 @@ contract('TrackedRedemption', accounts => { it("should get the exact details of the factory", async() => { assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); assert.equal(await I_TrackedRedemptionFactory.getType.call(), 5); + assert.equal(await I_TrackedRedemptionFactory.getVersion.call(), "1.0.0"); assert.equal(web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()) .replace(/\u0000/g, ''), "TrackedRedemption", From 16161ae83634f2f72d2742447f1b810e9b12738b Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 4 Oct 2018 16:12:38 +0530 Subject: [PATCH 041/142] General permission manager test case --- test/g_general_permission_manager.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 3b7299ca2..25ce783a9 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -399,6 +399,7 @@ contract('GeneralPermissionManager', accounts => { it("should get the exact details of the factory", async() => { assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); assert.equal(await I_GeneralPermissionManagerFactory.getType.call(),1); + assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), "1.0.0"); assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) .replace(/\u0000/g, ''), "GeneralPermissionManager", From f4869dd6d47c0816181401530cf677f6deef9281 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Thu, 4 Oct 2018 11:48:33 +0100 Subject: [PATCH 042/142] Fixes based on comments --- contracts/ModuleRegistry.sol | 2 +- contracts/libraries/TokenLib.sol | 14 +--------- .../modules/Checkpoint/DividendCheckpoint.sol | 4 +-- .../modules/Scheduled/CheckpointScheduler.sol | 0 contracts/tokens/SecurityToken.sol | 26 +++++++------------ 5 files changed, 13 insertions(+), 33 deletions(-) create mode 100644 contracts/modules/Scheduled/CheckpointScheduler.sol diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index 188745e98..c1269c331 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -159,7 +159,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { uint256 i; uint256 j; uint8[] memory moduleTypes = moduleFactory.getTypes(); - for (i = 0; i < moduleTypes.length; i++) { + for (i = 1; i < moduleTypes.length; i++) { for (j = 0; j < i; j++) { require(moduleTypes[i] != moduleTypes[j], "Type mismatch"); } diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index 8fa281d26..d09c17862 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -13,7 +13,6 @@ library TokenLib { uint8[] moduleTypes; uint256[] moduleIndexes; uint256 nameIndex; - mapping (uint8 => uint256) moduleIndex; } // Structures to maintain checkpoints of balances for governance / dividends @@ -125,18 +124,8 @@ library TokenLib { if (_currentCheckpointId == 0) { return; } - //No previous checkpoint data - add current balance against checkpoint - if (_checkpoints.length == 0) { - _checkpoints.push( - TokenLib.Checkpoint({ - checkpointId: _currentCheckpointId, - value: _newValue - }) - ); - return; - } //No new checkpoints since last update - if (_checkpoints[_checkpoints.length - 1].checkpointId == _currentCheckpointId) { + if ((_checkpoints.length > 0) && (_checkpoints[_checkpoints.length - 1].checkpointId == _currentCheckpointId)) { return; } //New checkpoint, so record balance @@ -148,5 +137,4 @@ library TokenLib { ); } - } diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 006ec1bde..1385637bc 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -132,8 +132,8 @@ contract DividendCheckpoint is ICheckpoint, Module { function pushDividendPayment(uint256 _dividendIndex, uint256 _start, uint256 _iterations) public withPerm(DISTRIBUTE) validDividendIndex(_dividendIndex) { Dividend storage dividend = dividends[_dividendIndex]; address[] memory investors = ISecurityToken(securityToken).getInvestors(); - uint256 numberInvestors = investors.length; - for (uint256 i = _start; i < Math.min256(numberInvestors, _start.add(_iterations)); i++) { + uint256 numberInvestors = Math.min256(investors.length, _start.add(_iterations)); + for (uint256 i = _start; i < numberInvestors; i++) { address payee = investors[i]; if ((!dividend.claimed[payee]) && (!dividend.dividendExcluded[payee])) { _payDividend(payee, dividend, _dividendIndex); diff --git a/contracts/modules/Scheduled/CheckpointScheduler.sol b/contracts/modules/Scheduled/CheckpointScheduler.sol new file mode 100644 index 000000000..e69de29bb diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index f19d392e9..7d466d1e5 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -618,14 +618,15 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return TokenLib.checkPermission(modules[PERMISSION_KEY], _delegate, _module, _perm); } - function _burn(address _from, uint256 _value) internal { + function _burn(address _from, uint256 _value) internal returns(bool) { require(_value <= balances[_from], "Value too high"); - require(_updateTransfer(_from, address(0), _value), "Transfer not valid"); + bool verified = _updateTransfer(_from, address(0), _value); _adjustTotalSupplyCheckpoints(); balances[_from] = balances[_from].sub(_value); totalSupply_ = totalSupply_.sub(_value); emit Burnt(_from, _value); emit Transfer(_from, address(0), _value); + return verified; } /** @@ -633,7 +634,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _value No. of tokens that get burned */ function burn(uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public { - _burn(msg.sender, _value); + require(_burn(msg.sender, _value), "Burn not valid"); } /** @@ -644,7 +645,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr function burnFrom(address _from, uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public { require(_value <= allowed[_from][msg.sender], "Value too high"); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); - _burn(_from, _value); + require(_burn(_from, _value), "Burn not valid"); } /** @@ -717,17 +718,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function forceTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController { require(_to != address(0)); - bool verified = _transfer(_from, _to, _value); - balances[_to] = balances[_to].add(_value); - emit ForceTransfer(msg.sender, _from, _to, _value, verified, _data); - emit Transfer(_from, _to, _value); - } - - function _transfer(address _from, address _to, uint256 _value) internal returns(bool) { require(_value <= balances[_from]); bool verified = _updateTransfer(_from, _to, _value); balances[_from] = balances[_from].sub(_value); - return verified; + balances[_to] = balances[_to].add(_value); + emit ForceTransfer(msg.sender, _from, _to, _value, verified, _data); + emit Transfer(_from, _to, _value); } /** @@ -737,12 +733,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _data data attached to the transfer by controller to emit in event */ function forceBurn(address _from, uint256 _value, bytes _data) public onlyController { - bool verified = _transfer(_from, address(0), _value); - _adjustTotalSupplyCheckpoints(); - totalSupply_ = totalSupply_.sub(_value); + bool verified = _burn(_from, _value); emit ForceBurn(msg.sender, _from, _value, verified, _data); - emit Burnt(_from, _value); - emit Transfer(_from, address(0), _value); } /** From a810f915c8d7879a6539f20f6f3a027c751f6096 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Thu, 4 Oct 2018 11:49:12 +0100 Subject: [PATCH 043/142] Remove empty module --- contracts/modules/Scheduled/CheckpointScheduler.sol | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 contracts/modules/Scheduled/CheckpointScheduler.sol diff --git a/contracts/modules/Scheduled/CheckpointScheduler.sol b/contracts/modules/Scheduled/CheckpointScheduler.sol deleted file mode 100644 index e69de29bb..000000000 From 2952dc42024f8d21aaf467f7707d0a43629df02d Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Thu, 4 Oct 2018 12:06:40 +0100 Subject: [PATCH 044/142] Add forceBurn to fuzz testing for checkpoints --- test/c_checkpoints.js | 54 +++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index 7f6a85960..d094a2dfc 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -223,9 +223,13 @@ contract('Checkpoints', accounts => { ); }); + it("Should set controller to token owner", async () => { + await I_SecurityToken.setController(token_owner, {from: token_owner}); + }); + it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); }); @@ -353,19 +357,39 @@ contract('Checkpoints', accounts => { await I_SecurityToken.transfer(receiver, amount, { from: sender }); } if (Math.random() > 0.5) { - let n = BigNumber(Math.random().toFixed(10)).mul(10**17).toFixed(0); - let p = Math.random() * 3; - let r = Math.random() * 3; - let minter; - if (r < 1) { - minter = account_investor1; - } else if (r < 2) { - minter = account_investor2; - } else { - minter = account_investor3; - } - console.log("Minting: " + n.toString() + " to: " + minter); - await I_SecurityToken.mint(minter, n, { from: token_owner }); + let n = BigNumber(Math.random().toFixed(10)).mul(10**17).toFixed(0); + let p = Math.random() * 3; + let r = Math.random() * 3; + let minter; + if (r < 1) { + minter = account_investor1; + } else if (r < 2) { + minter = account_investor2; + } else { + minter = account_investor3; + } + console.log("Minting: " + n.toString() + " to: " + minter); + await I_SecurityToken.mint(minter, n, { from: token_owner }); + } + if (Math.random() > 0.5) { + let n = BigNumber(Math.random().toFixed(10)).mul(10**17); + let p = Math.random() * 3; + let r = Math.random() * 3; + let burner; + if (r < 1) { + burner = account_investor1; + } else if (r < 2) { + burner = account_investor2; + } else { + burner = account_investor3; + } + let burnerBalance = BigNumber(await I_SecurityToken.balanceOf(burner)); + if (n.gt(burnerBalance.div(2))) { + n = burnerBalance.div(2); + } + n = n.toFixed(0); + console.log("Burning: " + n.toString() + " from: " + burner); + await I_SecurityToken.forceBurn(burner, n, "", { from: token_owner }); } console.log("Checking Interim..."); for (let k = 0; k < cps.length; k++) { From 7e2859be63aac7dfeefe235baed97677a37281a9 Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 17:24:06 +0530 Subject: [PATCH 045/142] minor fix --- contracts/modules/TransferManager/CountTransferManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/modules/TransferManager/CountTransferManager.sol b/contracts/modules/TransferManager/CountTransferManager.sol index 274dae2d8..565a03033 100644 --- a/contracts/modules/TransferManager/CountTransferManager.sol +++ b/contracts/modules/TransferManager/CountTransferManager.sol @@ -28,7 +28,7 @@ contract CountTransferManager is ITransferManager { /// @notice Used to verify the transfer transaction according to the rule implemented in the trnasfer managers function verifyTransfer(address /* _from */, address _to, uint256 /* _amount */, bool /* _isTransfer */) public returns(Result) { if (!paused) { - if (maxHolderCount < ISecurityToken(securityToken).investorCount()) { + if (maxHolderCount < ISecurityToken(securityToken).getInvestorCount()) { // Allow transfers to existing maxHolders if (ISecurityToken(securityToken).balanceOf(_to) != 0) { return Result.NA; From 6d8bcee90d038d96bc0f344b6735b21e2b2ce95d Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 18:29:42 +0530 Subject: [PATCH 046/142] remove investorCount --- contracts/interfaces/ISecurityToken.sol | 6 ------ 1 file changed, 6 deletions(-) diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index 09ffd2bb9..b0cbd22b1 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -116,12 +116,6 @@ interface ISecurityToken { */ function investors(uint256 _index) external view returns (address); - /** - * @notice gets the number of investors - * @return count of investors - */ - function investorCount() external view returns (uint256); - /** * @notice allows the owner to withdraw unspent POLY stored by them on the ST. * @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee. From fe52c2eaa8824b18153063ef14113d9fa3dd2283 Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 18:41:45 +0530 Subject: [PATCH 047/142] helper for PM ecosystem deployment --- test/b_capped_sto.js | 111 +++-------------- test/c_checkpoints.js | 122 +++---------------- test/d_count_transfer_manager.js | 140 +++------------------- test/e_erc20_dividends.js | 131 +++----------------- test/helpers/createInstances.js | 165 ++++++++++++++++++++++++++ test/l_percentage_transfer_manager.js | 114 +++--------------- test/n_security_token_registry.js | 72 +++++++++-- 7 files changed, 308 insertions(+), 547 deletions(-) create mode 100644 test/helpers/createInstances.js diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index ec216c637..13e8a4dc9 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -1,23 +1,15 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { encodeModuleCall } from './helpers/encodeCall'; +import { setUpPolymathNetwork } from './helpers/createInstances'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.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'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -108,8 +100,6 @@ contract('CappedSTO', accounts => { const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); const maxCost = cappedSTOSetupCost; const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; before(async() => { // Accounts setup @@ -121,41 +111,10 @@ contract('CappedSTO', accounts => { account_fundsReceiver = accounts[2]; token_owner = account_issuer; - // ----------- POLYMATH NETWORK Configuration ------------ + let instances = await setUpPolymathNetwork(account_polymath, token_owner); - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; // STEP 5: Deploy the GeneralDelegateManagerFactory @@ -177,47 +136,9 @@ contract('CappedSTO', accounts => { "CappedSTOFactory contract was not deployed" ); - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - + // STEP 7: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - console.log(await I_MRProxied.owner()); - console.log(account_polymath); - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); @@ -230,16 +151,16 @@ contract('CappedSTO', accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index a9094c6c5..9714e7602 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -1,21 +1,10 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall } from './helpers/encodeCall'; +import { setUpPolymathNetwork } from './helpers/createInstances'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -87,108 +76,25 @@ contract('Checkpoints', accounts => { account_investor3 = accounts[8]; account_investor4 = accounts[9]; - // ----------- POLYMATH NETWORK Configuration ------------ + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // Step 7: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 8: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 9: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 10: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 6: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); }); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 75c938939..663d32aed 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -1,23 +1,13 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { encodeModuleCall } from './helpers/encodeCall'; +import { setUpPolymathNetwork } from './helpers/createInstances'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); const CountTransferManagerFactory = artifacts.require('./CountTransferManagerFactory.sol'); const CountTransferManager = artifacts.require('./CountTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -42,7 +32,6 @@ contract('CountTransferManager', accounts => { let message = "Transaction Should Fail!"; // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; let I_SecurityTokenRegistryProxy; let P_CountTransferManagerFactory; let P_CountTransferManager; @@ -80,8 +69,6 @@ contract('CountTransferManager', accounts => { // CountTransferManager details const holderCount = 2; // Maximum number of token holders - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; let bytesSTO = encodeModuleCall(['uint256'], [holderCount]); before(async() => { @@ -95,60 +82,13 @@ contract('CountTransferManager', accounts => { account_investor2 = accounts[8]; account_investor3 = accounts[9]; - // ----------- POLYMATH NETWORK Configuration ------------ + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - assert.notEqual( - I_FeatureRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "FeatureRegistry contract was not deployed", - ); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 6: Deploy the CountTransferManager + // STEP 2: Deploy the CountTransferManager I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); assert.notEqual( I_CountTransferManagerFactory.address.valueOf(), @@ -156,7 +96,7 @@ contract('CountTransferManager', accounts => { "CountTransferManagerFactory contract was not deployed" ); - // STEP 7: Deploy Paid the CountTransferManager + // STEP 3: Deploy Paid the CountTransferManager P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); assert.notEqual( P_CountTransferManagerFactory.address.valueOf(), @@ -164,50 +104,6 @@ contract('CountTransferManager', accounts => { "CountTransferManagerFactory contract was not deployed" ); - // Step 9: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 10: Deploy the SecurityTokenRegistry - - // Deploy the SecurityTokenregistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 11: Deploy the proxy and attach the implementation contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 12: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 8: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the CountTransferManagerFactory await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); @@ -219,17 +115,15 @@ contract('CountTransferManager', accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} ----------------------------------------------------------------------------- `); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index e45808916..35e12492e 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -1,24 +1,13 @@ import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; +import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; +import { setUpPolymathNetwork } from './helpers/createInstances'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); const ERC20DividendCheckpointFactory = artifacts.require('./ERC20DividendCheckpointFactory.sol'); const ERC20DividendCheckpoint = artifacts.require('./ERC20DividendCheckpoint'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -45,7 +34,6 @@ contract('ERC20DividendCheckpoint', accounts => { let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; let I_GeneralTransferManagerFactory; let I_SecurityTokenRegistryProxy; let I_ERC20DividendCheckpointFactory; @@ -81,8 +69,6 @@ contract('ERC20DividendCheckpoint', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; before(async() => { // Accounts setup @@ -97,51 +83,11 @@ contract('ERC20DividendCheckpoint', accounts => { account_investor4 = accounts[9]; account_temp = accounts[2]; - // ----------- POLYMATH NETWORK Configuration ------------ + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; // STEP 6: Deploy the ERC20DividendCheckpoint P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); @@ -159,71 +105,28 @@ contract('ERC20DividendCheckpoint', accounts => { "ERC20DividendCheckpointFactory contract was not deployed" ); - // Step 9: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 10: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 11: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 12: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - // STEP 8: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the ERC20DividendCheckpointFactory + // (A) : Register the ERC20DividendCheckpointFactory await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - // (C) : Register the Paid ERC20DividendCheckpointFactory + // (B) : Register the Paid ERC20DividendCheckpointFactory await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} ERC20DividendCheckpointFactory: ${I_ERC20DividendCheckpointFactory.address} ----------------------------------------------------------------------------- `); diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js new file mode 100644 index 000000000..9369f3eba --- /dev/null +++ b/test/helpers/createInstances.js @@ -0,0 +1,165 @@ +import { encodeProxyCall, encodeModuleCall } from './encodeCall'; + +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +const SecurityToken = artifacts.require('./SecurityToken.sol'); +const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); +const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); +const SecurityTokenRegistryMock = artifacts.require('./SecurityTokenRegistryMock.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); +const STFactory = artifacts.require('./STFactory.sol'); +const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); +const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const PolyToken = artifacts.require('./PolyToken.sol'); +const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); + +const Web3 = require('web3'); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + + // Contract Instance Declaration + let I_GeneralTransferManagerFactory; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_SecurityToken; + let I_PolyToken; + let I_STFactory; + let I_PolymathRegistry; + let I_SecurityTokenRegistryProxy; + let I_STRProxied; + let I_MRProxied; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + +export async function setUpPolymathNetwork(account_polymath, token_owner) { + // ----------- POLYMATH NETWORK Configuration ------------ + // Step 1: Deploy the PolyToken and PolymathRegistry + let a = await deployPolyRegistryAndPolyToken(account_polymath, token_owner); + // Step 2: Deploy the FeatureRegistry + let b = await deployFeatureRegistry(account_polymath); + // STEP 3: Deploy the ModuleRegistry + let c = await deployModuleRegistry(account_polymath); + // STEP 4: Deploy the GeneralTransferManagerFactory + let d = await deployGTM(account_polymath); + // Step 6: Deploy the STversionProxy contract + let e = await deploySTFactory(account_polymath); + // Step 7: Deploy the SecurityTokenRegistry + let f = await deploySTR(account_polymath); + // Step 8: update the registries addresses from the PolymathRegistry contract + await setInPolymathRegistry(account_polymath); + // STEP 9: Register the Modules with the ModuleRegistry contract + await registerGTM(account_polymath); + let tempArray = new Array(a, b, c, d, e, f); + return mergeReturn(tempArray); + +} + + +function mergeReturn(returnData) { + let returnArray = new Array(); + for (let i = 0; i < returnData.length; i++) { + for (let j = 0; j < returnData[i].length; j++) { + returnArray.push(returnData[i][j]); + } + } + return returnArray; + +} + + +async function deployPolyRegistryAndPolyToken(account_polymath, token_owner) { + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + return new Array(I_PolymathRegistry, I_PolyToken); +} + +async function deployFeatureRegistry(account_polymath) { + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + return new Array(I_FeatureRegistry) +} + +async function deployModuleRegistry(account_polymath) { + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + return new Array(I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied); +} + +async function deployGTM(account_polymath) { + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + return new Array(I_GeneralTransferManagerFactory); +} + +async function deploySTFactory(account_polymath) { + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + return new Array(I_STFactory); +} + +async function deploySTR(account_polymath) { + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 9 (a): Deploy the proxy + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + return new Array(I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied); +} + +async function setInPolymathRegistry(account_polymath) { + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); +} + +async function registerGTM(account_polymath) { + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); +} diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 4e81888f4..771330122 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -1,23 +1,14 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { setUpPolymathNetwork } from './helpers/createInstances'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); const PercentageTransferManagerFactory = artifacts.require('./PercentageTransferManagerFactory.sol'); const PercentageTransferManager = artifacts.require('./PercentageTransferManager'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); +const SecurityToken = artifacts.require('./SecurityToken.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -60,7 +51,7 @@ contract('PercentageTransferManager', accounts => { let I_STFactory; let I_SecurityToken; let I_PolyToken; - let I_PolymathRegistry; + var I_PolymathRegistry; // SecurityToken Details const name = "Team"; @@ -90,9 +81,6 @@ contract('PercentageTransferManager', accounts => { ] }, [holderPercentage]); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - before(async() => { // Accounts setup account_polymath = accounts[0]; @@ -104,41 +92,10 @@ contract('PercentageTransferManager', accounts => { account_investor2 = accounts[8]; account_investor3 = accounts[9]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry + let instances = await setUpPolymathNetwork(account_polymath, token_owner); - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4(a): Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; // STEP 4(b): Deploy the GeneralDelegateManagerFactory @@ -167,45 +124,6 @@ contract('PercentageTransferManager', accounts => { ); - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); @@ -221,16 +139,16 @@ contract('PercentageTransferManager', accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} PercentageTransferManagerFactory: ${I_PercentageTransferManagerFactory.address} ----------------------------------------------------------------------------- diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 2639e098d..8c5c611a7 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -193,9 +193,6 @@ contract('SecurityTokenRegistry', accounts => { // Step 9 (a): Deploy the proxy I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); // Step 10: Deploy the FeatureRegistry @@ -249,6 +246,63 @@ contract('SecurityTokenRegistry', accounts => { `); }); + describe("Test the initialize the function", async() => { + + it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, ["0x0000000000000000000000000000000000000000", I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because polymathRegistry address is 0x" + ); + }) + + it("Should successfully update the implementation address -- fail because STFactory address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, "0x0000000000000000000000000000000000000000", initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because STFactory address is 0x" + ); + }); + + it("Should successfully update the implementation address -- fail because STLaunch fee is 0", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, 0, initRegFee, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because STLaunch fee is 0" + ); + }); + + it("Should successfully update the implementation address -- fail because tickerRegFee fee is 0", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, 0, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because tickerRegFee is 0" + ); + }); + + it("Should successfully update the implementation address -- fail because PolyToken address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, "0x0000000000000000000000000000000000000000", account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because PolyToken address is 0x" + ); + }); + + it("Should successfully update the implementation address -- fail because owner address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, "0x0000000000000000000000000000000000000000"]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because owner address is 0x" + ); + }); + + it("Should successfully update the implementation address", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + }); + }) + describe(" Test cases of the registerTicker", async() => { @@ -935,7 +989,7 @@ contract('SecurityTokenRegistry', accounts => { let tx = await I_STRProxied.registerTicker(account_temp, "TOK1", "", { from: account_temp }); assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK1", `Symbol should be TOK1`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); it("Should register the ticker 2", async () => { @@ -944,7 +998,7 @@ contract('SecurityTokenRegistry', accounts => { let tx = await I_STRProxied.registerTicker(account_temp, "TOK2", "", { from: account_temp }); assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK2", `Symbol should be TOK2`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); it("Should register the ticker 3", async () => { @@ -953,13 +1007,13 @@ contract('SecurityTokenRegistry', accounts => { let tx = await I_STRProxied.registerTicker(account_temp, "TOK3", "", { from: account_temp }); assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK3", `Symbol should be TOK3`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); it("Should successfully remove the ticker 2", async() => { let tx = await I_STRProxied.removeTicker("TOK2", {from: account_polymath}); assert.equal(tx.logs[0].args._ticker, "TOK2", "Ticker doesn't get deleted successfully"); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); it("Should modify ticker 1", async() => { @@ -967,7 +1021,7 @@ contract('SecurityTokenRegistry', accounts => { assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK1", "Should be equal to TOK1"); assert.equal(tx.logs[0].args._name, "TOKEN 1", "Should be equal to TOKEN 1"); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }) it("Should modify ticker 3", async() => { @@ -975,7 +1029,7 @@ contract('SecurityTokenRegistry', accounts => { assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK3", "Should be equal to TOK3"); assert.equal(tx.logs[0].args._name, "TOKEN 3", "Should be equal to TOKEN 3"); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toAscii(x))); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }) }); From c056227035edf03c9834ec2087954eecdb55b1ce Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 4 Oct 2018 15:34:29 +0200 Subject: [PATCH 048/142] fixes done --- .node-xmlhttprequest-content-39801 | 1 - .../GeneralPermissionManager.sol | 63 +++++++++++++------ .../PermissionManager/IPermissionManager.sol | 10 +++ test/g_general_permission_manager.js | 10 +-- 4 files changed, 60 insertions(+), 24 deletions(-) delete mode 100644 .node-xmlhttprequest-content-39801 diff --git a/.node-xmlhttprequest-content-39801 b/.node-xmlhttprequest-content-39801 deleted file mode 100644 index 451f07b26..000000000 --- a/.node-xmlhttprequest-content-39801 +++ /dev/null @@ -1 +0,0 @@ -{"err":{"errno":"ECONNREFUSED","code":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":8545}} \ No newline at end of file diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 35fb6b7ef..494b5a2d9 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -8,7 +8,7 @@ import "../Module.sol"; */ contract GeneralPermissionManager is IPermissionManager, Module { - // Mapping used to hold the permissions on the modules provided to delegate, delegate add => modules add => permission uint8 => bool + // Mapping used to hold the permissions on the modules provided to delegate, module add => delegate add => permission uint8 => bool mapping (address => mapping (address => mapping (bytes32 => bool))) public perms; // Mapping hold the delagate details mapping (address => bytes32) public delegateDetails; @@ -22,7 +22,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { /// Event emitted after any permission get changed for the delegate event ChangePermission(address _delegate, address _module, bytes32 _perm, bool _valid, uint256 _timestamp); /// Use to notify when delegate is added in permission manager contract - event LogAddDelegate(address _delegate, bytes32 _details, uint256 _timestamp); + event AddDelegate(address indexed _delegate, bytes32 _details, uint256 _timestamp); /// @notice constructor @@ -62,7 +62,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { require(_details != bytes32(0), "Delegate details not set"); delegateDetails[_delegate] = _details; allDelegates.push(_delegate); - emit LogAddDelegate(_delegate, _details, now); + emit AddDelegate(_delegate, _details, now); } /** @@ -112,7 +112,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @param _potentialDelegate the address of potential delegate * @return bool */ - function isDelegate(address _potentialDelegate) public view returns(bool) { + function checkDelegate(address _potentialDelegate) public view returns(bool) { require(_potentialDelegate != address(0)); @@ -130,7 +130,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @param _multiPerms Multiple permission flag needs to be changed * @return nothing */ - function changePermissionBulk( + function changePermissionMulti( address _delegate, address[] _multiModules, bytes32[] _multiPerms @@ -140,6 +140,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { { require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); require(_multiModules.length != 0 && _multiPerms.length !=0); + require(_multiModules.length == _multiPerms.length, "modules and permission length are not same"); for(uint8 i=0;i<_multiPerms.length;i++){ bool _currentPerm = !perms[_multiModules[i]][_delegate][_multiPerms[i]]; @@ -155,23 +156,33 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @return address[] */ - address[] allDelegatesWithPerm; - function getAllDelegatesWithPerm(address _module, bytes32 _perm) public returns(address[]) { + function getAllDelegatesWithPerm(address _module, bytes32 _perm) public view returns(address[]) { require(_module != address(0) && _perm != bytes32(0)); + uint256 counter = 0; + + for(uint8 j=0;jgetModulesByType for(uint8 i=0; i<_types.length; i++){ address[] memory _currentTypeModules = ISecurityToken(_tokenAddress).getModulesByType(_types[i]); @@ -198,16 +207,34 @@ contract GeneralPermissionManager is IPermissionManager, Module { // loop through each perm, if it is true, push results into arrays for (uint8 b=0; b<_allModulePerms.length; b++){ if(perms[_currentTypeModules[a]][_delegate][_allModulePerms[b]]){ - _allModules.push(_currentTypeModules[a]); - _allPerms.push(_allModulePerms[b]); + counter ++; } } } } - return(_allModules, _allPerms); - } + address[] memory _allModules = new address[](counter); + bytes32[] memory _allPerms = new bytes32[](counter); + + counter=0; + for( i=0; i<_types.length; i++){ + _currentTypeModules = ISecurityToken(_tokenAddress).getModulesByType(_types[i]); + + for(a=0; a<_currentTypeModules.length; a++){ + _allModulePerms = IModule(_currentTypeModules[a]).getPermissions(); + for (b=0; b<_allModulePerms.length; b++){ + if(perms[_currentTypeModules[a]][_delegate][_allModulePerms[b]]){ + _allModules[counter]= _currentTypeModules[a]; + _allPerms[counter]=_allModulePerms[b]; + counter++; + } + } + } + } + + return(_allModules, _allPerms); + } } diff --git a/contracts/modules/PermissionManager/IPermissionManager.sol b/contracts/modules/PermissionManager/IPermissionManager.sol index a893beee4..3039b97c0 100644 --- a/contracts/modules/PermissionManager/IPermissionManager.sol +++ b/contracts/modules/PermissionManager/IPermissionManager.sol @@ -7,6 +7,16 @@ interface IPermissionManager { function checkPermission(address _delegate, address _module, bytes32 _perm) external view returns(bool); + function getPermissions() external view returns(bytes32[]); + + function getAllDelegates() external view returns(address[]); + + function checkDelegate(address _potentialDelegate) external view returns(bool); + + function getAllDelegatesWithPerm(address _module, bytes32 _perm) external view returns(address[]); + + function getAllModulesAndPermsFromTypes(address _delegate, uint8[] _types, address _tokenAddress) public view returns(address[], bytes32[]); + function changePermission(address _delegate, address _module, bytes32 _perm, bool _valid) external returns(bool); } diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 84dd342af..fa6645732 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -421,18 +421,18 @@ contract('GeneralPermissionManager', accounts => { }); it("Should return false when check is delegate - because user is not a delegate", async() => { - assert.equal(await I_GeneralPermissionManager.isDelegate.call(account_investor1), false); + assert.equal(await I_GeneralPermissionManager.checkDelegate.call(account_investor1), false); }); it("Should return true when check is delegate - because user is a delegate", async() => { - assert.equal(await I_GeneralPermissionManager.isDelegate.call(account_delegate), true); + assert.equal(await I_GeneralPermissionManager.checkDelegate.call(account_delegate), true); }); it("Should provide the permission in bulk", async() => { await I_GeneralPermissionManager.addDelegate(account_delegate3, delegateDetails, { from: token_owner}); - let tx = await I_GeneralPermissionManager.changePermissionBulk(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], ["WHITELIST","CHANGE_PERMISSION"], {from: token_owner}); + let tx = await I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], ["WHITELIST","CHANGE_PERMISSION"], {from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate3); assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate3, I_GeneralTransferManager.address, "WHITELIST")); @@ -453,8 +453,8 @@ contract('GeneralPermissionManager', accounts => { it("Should return all modules and all permission", async() => { - let tx = await I_GeneralPermissionManager.getAllModulesAndPerms.call(account_delegate3, [2,1], I_SecurityToken.address); - // console.log (tx); + let tx = await I_GeneralPermissionManager.getAllModulesAndPermsFromTypes.call(account_delegate3, [2,1], I_SecurityToken.address); + console.log (tx); assert.equal(tx[0][0], I_GeneralTransferManager.address); assert.equal(tx[1][0], "0x57484954454c4953540000000000000000000000000000000000000000000000"); assert.equal(tx[0][1], I_GeneralPermissionManager.address); From 1b4a5497f0a580f3a166980cb7b96570a32123ac Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Thu, 4 Oct 2018 15:19:25 +0100 Subject: [PATCH 049/142] Small update --- contracts/modules/TransferManager/ITransferManager.sol | 1 + contracts/tokens/SecurityToken.sol | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/contracts/modules/TransferManager/ITransferManager.sol b/contracts/modules/TransferManager/ITransferManager.sol index 5d23a37fd..8279e68c5 100644 --- a/contracts/modules/TransferManager/ITransferManager.sol +++ b/contracts/modules/TransferManager/ITransferManager.sol @@ -5,6 +5,7 @@ import "../Module.sol"; /** * @title Interface to be implemented by all Transfer Manager modules + * @dev abstract contract */ contract ITransferManager is Module, Pausable { diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index ac8edd049..83724284e 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -238,12 +238,9 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint256 i; for (i = 0; i < moduleTypes.length; i++) { moduleIndexes[i] = modules[moduleTypes[i]].length; - } - modulesToData[module] = TokenLib.ModuleData(moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length); - for (i = 0; i < moduleTypes.length; i++) { - /* modulesToData[module].moduleType[moduleTypes[i]] = true; */ 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 emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, now); From 35a2cc1963bc6c3cdf15dacaeca5e5b6193fc855 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 4 Oct 2018 17:25:17 +0200 Subject: [PATCH 050/142] fixed function name in transfer manager test --- test/h_general_transfer_manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 36eccdbb0..a7b2aaf2f 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -569,7 +569,7 @@ contract('GeneralTransferManager', accounts => { }); it("Should provide the permission and change the signing address", async() => { - let log = await I_GeneralPermissionManager.addPermission(account_delegate, "My details", {from: token_owner}); + let log = await I_GeneralPermissionManager.addDelegate(account_delegate, "My details", {from: token_owner}); assert.equal(log.logs[0].args._delegate, account_delegate); await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FLAGS", true, {from: token_owner}); From b9247bdee2ce34060c67b690591105446574c492 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 4 Oct 2018 18:29:12 +0200 Subject: [PATCH 051/142] fixed issuerance & security token test files --- test/i_Issuance.js | 2 +- test/o_security_token.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 4cfe448d3..479f71d26 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -323,7 +323,7 @@ contract('Issuance', accounts => { let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath}); + await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_polymath}); // Providing the permission to the delegate await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: account_polymath }); diff --git a/test/o_security_token.js b/test/o_security_token.js index 1217c6c22..13763718a 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -745,7 +745,7 @@ contract('SecurityToken', accounts => { let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); try { - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp }); + await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_temp }); } catch (error) { console.log(`${account_temp} doesn't have permissions to register the delegate`); errorThrown = true; @@ -756,7 +756,7 @@ contract('SecurityToken', accounts => { it("Should provide the permission to the delegate to change the transfer bools", async () => { // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); + await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner}); // Providing the permission to the delegate await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: token_owner }); From b09148c026d7effa810566e4c0317aa425211a22 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 4 Oct 2018 22:06:33 +0530 Subject: [PATCH 052/142] WIP catchRevert --- ex.js | 31 + test/a_poly_oracle.js | 59 +- test/b_capped_sto.js | 260 +-- test/d_count_transfer_manager.js | 39 +- test/f_ether_dividends.js | 198 +-- test/g_general_permission_manager.js | 37 +- test/h_general_transfer_manager.js | 176 +- test/helpers/exceptions.js | 52 +- test/j_manual_approval_transfer_manager.js | 136 +- test/k_module_registry.js | 127 +- test/l_percentage_transfer_manager.js | 19 +- test/m_presale_sto.js | 47 +- test/n_security_token_registry.js | 9 +- test/o_security_token.js | 407 +---- test/p_usd_tiered_sto.js | 1761 ++------------------ test/q_usd_tiered_sto_sim.js | 18 +- test/t_security_token_registry_proxy.js | 73 +- test/u_module_registry_proxy.js | 73 +- test/v_tracked_redemptions.js | 10 +- 19 files changed, 412 insertions(+), 3120 deletions(-) create mode 100644 ex.js diff --git a/ex.js b/ex.js new file mode 100644 index 000000000..97a5fb222 --- /dev/null +++ b/ex.js @@ -0,0 +1,31 @@ +var fs = require('fs') +const regex = /(?<=try {)(.*?)(await )(.*?)(?=;)(.*?)(?=message\);)/gmis; +const regex2 = /(try {)(.*?)(message\);)/gmis; +let m; + +const dirname = 'test/'; +fs.readdir(dirname, function(err, filenames) { + if (err) { + return console.log(err); + } + filenames.forEach(function(filename) { + fs.readFile(dirname + filename, 'utf-8', function(err, content) { + if (err) { + return console.log(err); + } + content = content.replace(regex, 'catchRevert($3);'); + content = content.replace(regex2, 'await $2'); + fs.writeFile(dirname + filename, content, 'utf8', function (err) { + if (err) return console.log(err); + }); + }); + }); +}); + + + + + + + + diff --git a/test/a_poly_oracle.js b/test/a_poly_oracle.js index f727b4014..23ca4f6e0 100644 --- a/test/a_poly_oracle.js +++ b/test/a_poly_oracle.js @@ -2,6 +2,7 @@ const PolyOracle = artifacts.require('./MockPolyOracle.sol'); import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import {increaseTime} from './helpers/time'; +import { catchRevert } from './helpers/exceptions'; const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -56,27 +57,13 @@ let requestIds = new Array(); it("Should schedule the timing of the call - fails - non owner", async() => { let errorThrown = false; let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] - try { - await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: accounts[1], value: web3.utils.toWei("2")}); - } catch(error) { - errorThrown = true; - ensureException(error); - console.log(` tx -> revert msg.sender should be the owner of the contract`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: accounts[1], value: web3.utils.toWei("2")})); }); it("Should schedule the timing of the call - fails - no value", async() => { let errorThrown = false; let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] - try { - await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner}); - } catch(error) { - errorThrown = true; - ensureException(error); - console.log(` tx -> revert Because value for txn is not provided`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner})); }) it("Should schedule the timing of the call - single call", async() => { @@ -116,13 +103,7 @@ let requestIds = new Array(); it("Should schedule to call using iters - fails", async() => { let errorThrown = false; - try { - await I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, {from: accounts[6]}); - } catch(error) { - errorThrown = true; - console.log(` tx->revert msg.sender is not the owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, {from: accounts[6]})); }) it("Should schedule to call using iters", async() => { @@ -150,13 +131,7 @@ let requestIds = new Array(); it("Should change the Poly USD price manually - fail - bad account", async() => { let errorThrown = false; - try { - await I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: accounts[5]}); - } catch(error) { - errorThrown = true; - console.log(` tx->revert msg.sender is not the owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: accounts[5]})); }); it("Should change the Poly USD price manually", async() => { @@ -167,13 +142,7 @@ let requestIds = new Array(); it("Should freeze the Oracle manually", async() => { let errorThrown = false; - try { - await I_PolyOracle.setFreezeOracle(true, {from: accounts[5]}); - } catch(error) { - errorThrown = true; - console.log(` tx->revert msg.sender is not the owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.setFreezeOracle(true, {from: accounts[5]})); }) it("Should change the URL manually", async() => { @@ -187,13 +156,7 @@ let requestIds = new Array(); it("Should change the sanity bounds manually - fails - bad owner", async() => { let errorThrown = false; - try { - await I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : accounts[6]}); - } catch(error) { - errorThrown = true; - console.log(` tx->revert msg.sender is not the owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : accounts[6]})); }) it("Should change the sanity bounds manually", async() => { @@ -299,13 +262,7 @@ let requestIds = new Array(); it("should change the api URL manually", async() => { let errorThrown = false; - try { - await I_PolyOracle.setOracleURL(alternateURL, {from: accounts[6]}); - } catch(error){ - errorThrown = true; - console.log(` tx->revert msg.sender is not the owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.setOracleURL(alternateURL, {from: accounts[6]})); }) it("should change the api URL manually", async() => { diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 13e8a4dc9..ba431e1db 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -3,6 +3,7 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeModuleCall } from './helpers/encodeCall'; import { setUpPolymathNetwork } from './helpers/createInstances'; +import { catchRevert } from './helpers/exceptions'; const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); @@ -201,14 +202,7 @@ contract('CappedSTO', accounts => { it("Should mint the tokens before attaching the STO", async() => { let errorThrown = false; - try { - await I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), {from: token_owner}); - } catch (error) { - console.log(` tx -> revert 0x address is not allowed as investor`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), {from: token_owner})); }); it("Should fail to launch the STO due to security token doesn't have the sufficient POLY", async () => { @@ -218,14 +212,7 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; - try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Rate is ${0}. Test Passed Successfully`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to launch the STO due to rate is 0", async () => { @@ -235,27 +222,13 @@ contract('CappedSTO', accounts => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; - try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - } catch(error) { - console.log(`Tx Failed because of rate is ${0}. Test Passed Successfully`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to launch the STO due to startTime > endTime", async () => { let bytesSTO = encodeModuleCall(STOParameters, [ Math.floor(Date.now()/1000 + 100000), Math.floor(Date.now()/1000 + 1000), cap, rate, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; - try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - } catch(error) { - errorThrown = true; - console.log(` tx revert -> StartTime is greater than endTime. Test Passed Successfully`.grey); - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to launch the STO due to cap is of 0 securityToken", async () => { @@ -263,14 +236,7 @@ contract('CappedSTO', accounts => { let endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [ startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); let errorThrown = false; - try { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - } catch(error) { - console.log(`Tx Failed because the Cap is equal to ${0}. Test Passed Successfully`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should successfully attach the STO module to the security token", async () => { @@ -320,66 +286,38 @@ contract('CappedSTO', accounts => { it("Should buy the tokens -- failed due to startTime is greater than Current time", async () => { let errorThrown = false; - try { - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, value: web3.utils.toWei('1', 'ether') - }); - } catch(error) { - console.log(` tx revert -> startTime is greater than Current time`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); it("Should buy the tokens -- failed due to invested amount is zero", async () => { let errorThrown = false; - try { - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, value: web3.utils.toWei('0', 'ether') - }); - } catch(error) { - console.log(` tx revert -> Invested amount is zero`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { let errorThrown = false; - try { - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, value: web3.utils.toWei('1', 'ether') - }); - } catch(error) { - console.log(` tx revert -> Investor doesn't present in the whitelist`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + })); }); it("Should buy the tokens -- Failed due to wrong granularity", async () => { let errorThrown = false; - try { - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, value: web3.utils.toWei('0.1111', 'ether') - }); - } catch(error) { - console.log(` tx revert -> Wrong purchase granularity`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + })); }); it("Should Buy the tokens", async() => { @@ -449,14 +387,7 @@ contract('CappedSTO', accounts => { it("Should pause the STO -- Failed due to wrong msg.sender", async()=> { let errorThrown = false; - try { - let tx = await I_CappedSTO_Array_ETH[0].pause({from: account_investor1}); - } catch(error) { - console.log(` tx revert -> Wrong msg.sender`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTO_Array_ETH[0].pause({from: account_investor1})); }); it("Should pause the STO", async()=> { @@ -467,31 +398,17 @@ contract('CappedSTO', accounts => { it("Should fail to buy the tokens after pausing the STO", async() => { let errorThrown = false; - try { - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, gas: 2100000, value: web3.utils.toWei('1', 'ether') - }); - } catch(error) { - console.log(` tx revert -> STO is paused`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + })); }); it("Should unpause the STO -- Failed due to wrong msg.sender", async()=> { let errorThrown = false; - try { - let tx = await I_CappedSTO_Array_ETH[0].unpause({from: account_investor1}); - } catch(error) { - console.log(` tx revert -> Wrong msg.sender`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTO_Array_ETH[0].unpause({from: account_investor1})); }); it("Should unpause the STO", async()=> { @@ -501,18 +418,11 @@ contract('CappedSTO', accounts => { it("Should buy the tokens -- Failed due to wrong granularity", async () => { let errorThrown = false; - try { - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, value: web3.utils.toWei('0.1111', 'ether') - }); - } catch(error) { - console.log(` tx revert -> Wrong purchase granularity`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + })); }); it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async() => { @@ -552,37 +462,12 @@ contract('CappedSTO', accounts => { .toNumber(), 9000 ); - try { - // Fallback transaction - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_investor2, to: I_CappedSTO_Array_ETH[0].address, gas: 210000, value: web3.utils.toWei('1', 'ether') - }); - } catch(error) { - console.log(` tx revert -> Cap reached`.grey); - ensureException(error); - } - }); - - it("Should failed at the time of buying the tokens -- Because STO get expired", async() => { - await increaseTime(duration.days(17)); // increased beyond the end time of the STO - let errorThrown = false; - try { - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO_Array_ETH[0].address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); - } catch(error) { - console.log(` tx revert -> STO get expired reached`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { @@ -614,14 +499,7 @@ contract('CappedSTO', accounts => { await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); let errorThrown = false; - try { - await I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner }); - } catch(error) { - console.log(` tx revert -> token contract address is 0 address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); }); it("Should successfully reclaim POLY", async() => { @@ -708,14 +586,7 @@ contract('CappedSTO', accounts => { // Buying on behalf of another user should fail let errorThrown = false; - try { - await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') }); - } catch(error) { - console.log(` tx revert -> incorrect beneficiary`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') })); }); @@ -975,38 +846,13 @@ contract('CappedSTO', accounts => { 45000 ); let errorThrown = false; - try { - - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}); - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (1000 * Math.pow(10, 18)), - {from : account_investor1, gas: 6000000 } - ); - } catch(error) { - console.log(` tx revert -> Cap reached`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); }); it("Should failed at the time of buying the tokens -- Because STO get expired", async() => { await increaseTime(duration.days(31)); // increased beyond the end time of the STO let errorThrown = false; - try { - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}); - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (1000 * Math.pow(10, 18)), - {from : account_investor1, gas: 6000000 } - ); - } catch(error) { - console.log(` tx revert -> STO expiry reached`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); }); it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { @@ -1043,26 +889,12 @@ contract('CappedSTO', accounts => { it("Should fail to change the title -- bad owner", async() => { let errorThrown = false; - try { - await I_CappedSTOFactory.changeTitle("STO Capped", {from:account_investor1}); - } catch(error) { - console.log(` tx revert -> bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTOFactory.changeTitle("STO Capped", {from:account_investor1})); }); it("Should fail to change the title -- zero length", async() => { let errorThrown = false; - try { - await I_CappedSTOFactory.changeTitle("", {from: token_owner}); - } catch(error) { - console.log(` tx revert -> bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTOFactory.changeTitle("", {from: token_owner})); }); it("Should successfully change the title", async() => { @@ -1074,26 +906,12 @@ contract('CappedSTO', accounts => { it("Should fail to change the description -- bad owner", async() => { let errorThrown = false; - try { - await I_CappedSTOFactory.changeDescription("It is only a STO", {from:account_investor1}); - } catch(error) { - console.log(` tx revert -> bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTOFactory.changeDescription("It is only a STO", {from:account_investor1})); }); it("Should fail to change the description -- zero length", async() => { let errorThrown = false; - try { - await I_CappedSTOFactory.changeDescription("", {from: token_owner}); - } catch(error) { - console.log(` tx revert -> length of string should not be zero`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTOFactory.changeDescription("", {from: token_owner})); }); it("Should successfully change the description", async() => { @@ -1105,26 +923,12 @@ contract('CappedSTO', accounts => { it("Should fail to change the name -- bad owner", async() => { let errorThrown = false; - try { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from:account_investor1}); - } catch(error) { - console.log(` tx revert -> bad owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from:account_investor1})); }); it("Should fail to change the name -- zero length", async() => { let errorThrown = false; - try { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex(""), {from: token_owner}); - } catch(error) { - console.log(` tx revert -> length of string should not be zero`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(""), {from: token_owner})); }); it("Should successfully change the name", async() => { diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 663d32aed..c2c7b631f 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -3,6 +3,7 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeModuleCall } from './helpers/encodeCall'; import { setUpPolymathNetwork } from './helpers/createInstances'; +import { catchRevert } from './helpers/exceptions'; const SecurityToken = artifacts.require('./SecurityToken.sol'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); @@ -167,14 +168,7 @@ contract('CountTransferManager', accounts => { it("Should successfully attach the CountTransferManager factory with the security token", async () => { let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); it("Should successfully attach the CountTransferManager factory with the security token", async () => { @@ -276,15 +270,7 @@ contract('CountTransferManager', accounts => { assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); let errorThrown = false; - try { - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Too many holders`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner })); }); @@ -312,14 +298,7 @@ contract('CountTransferManager', accounts => { it("Should fail in modifying the holder count", async() => { let errorThrown = false; - try { - await I_CountTransferManager.changeHolderCount(1, { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> Only owner have the permission to change the holder count`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_CountTransferManager.changeHolderCount(1, { from: account_investor1 })); }) it("Modify holder count to 1", async() => { @@ -347,15 +326,7 @@ contract('CountTransferManager', accounts => { it("Should not be able to transfer to a new token holder", async() => { let errorThrown = false; // await I_CountTransferManager.unpause({from: token_owner}); - try { - // Mint some tokens - await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> Too many holders`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 })); }); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index aff9c6f49..9773398c1 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -268,14 +268,7 @@ contract('EtherDividendCheckpoint', accounts => { it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { @@ -365,42 +358,21 @@ contract('EtherDividendCheckpoint', accounts => { let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - try { - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because msg.value = 0`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner})); }); it("Should fail in creating the dividend", async() => { let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() - duration.days(10); - try { - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); - } catch(error) { - console.log(` tx -> failed because maturity > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); }); it("Should fail in creating the dividend", async() => { let errorThrown = false; let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); - try { - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); - } catch(error) { - console.log(` tx -> failed because now > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); }); it("Set withholding tax of 20% on investor 2", async() => { @@ -411,14 +383,7 @@ contract('EtherDividendCheckpoint', accounts => { let errorThrown = false; let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - try { - await I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); - } catch(error) { - console.log(` tx -> failed because dividend name is empty`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); }); it("Create new dividend", async() => { @@ -437,40 +402,19 @@ contract('EtherDividendCheckpoint', accounts => { it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { let errorThrown = false; - try { - await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because dividend index has maturity in future`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { let errorThrown = false; // Increase time by 2 day await increaseTime(duration.days(2)); - try { - await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}); - } catch(error) { - console.log(` tx -> failed because msg.sender is not the owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp})); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { let errorThrown = false; - try { - await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because dividend index is greator than the dividend array length`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner})); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { @@ -541,28 +485,14 @@ contract('EtherDividendCheckpoint', accounts => { it("Issuer pushes dividends fails due to passed expiry", async() => { let errorThrown = false; await increaseTime(duration.days(12)); - try { - await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); - } catch(error) { - console.log(` tx -> failed because dividend index has passed its expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); }); it("Issuer reclaims dividend", async() => { let errorThrown = false; let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); - try { - await I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); - } catch(error) { - console.log(` tx -> failed because dividend index has already reclaimed`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000})); }); it("Still no more withholding tax to withdraw", async() => { @@ -609,14 +539,7 @@ contract('EtherDividendCheckpoint', accounts => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - try { - await I_EtherDividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend index is not valid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0})); }); it("Should investor 3 claims dividend", async() => { @@ -641,14 +564,7 @@ contract('EtherDividendCheckpoint', accounts => { it("should investor 3 claims dividend", async() => { let errorThrown = false; - try { - await I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because investor already claimed the dividend`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0})); }); it("Issuer pushes remainder", async() => { @@ -685,56 +601,28 @@ contract('EtherDividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); - try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: 0}); - } catch(error) { - console.log(` tx -> failed because msg.value is 0`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: 0})); }); it("Create another new dividend with explicit", async() => { let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() - duration.days(10); - try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); - } catch(error) { - console.log(` tx -> failed because maturity > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); }); it("Create another new dividend with bad expirty - fails", async() => { let errorThrown = false; let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); - try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); - } catch(error) { - console.log(` tx -> failed because now > expiry`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); }); it("Create another new dividend with bad checkpoint in the future - fails", async() => { let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(2); - try { - tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); - } catch(error) { - console.log(` tx -> failed because checkpoint id > current checkpoint`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); }); it("Should not create dividend with more exclusions than limit", async() => { @@ -766,14 +654,7 @@ contract('EtherDividendCheckpoint', accounts => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - try { - await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because not called by the owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0})); }); it("issuer pushes investor 1 with bad dividend index - fails", async() => { @@ -781,14 +662,7 @@ contract('EtherDividendCheckpoint', accounts => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - try { - await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend index is not valid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0})); }); it("should calculate dividend before the push dividend payment", async() => { @@ -850,27 +724,13 @@ contract('EtherDividendCheckpoint', accounts => { it("Issuer unable to reclaim dividend (expiry not passed)", async() => { let errorThrown = false; - try { - await I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner}); - } catch(error) { - console.log(`Tx Failed because expiry is in the future ${0}. Test Passed Successfully`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner})); }); it("Issuer is able to reclaim dividend after expiry", async() => { let errorThrown = false; await increaseTime(11 * 24 * 60 * 60); - try { - await I_EtherDividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend index is not valid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0})); }); it("Issuer is able to reclaim dividend after expiry", async() => { @@ -882,26 +742,12 @@ contract('EtherDividendCheckpoint', accounts => { it("Issuer is able to reclaim dividend after expiry", async() => { let errorThrown = false; - try { - await I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); - } catch(error) { - console.log(` tx -> failed because dividend are already reclaimed`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0})); }); it("Investor 3 unable to pull dividend after expiry", async() => { let errorThrown = false; - try { - await I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}); - } catch(error) { - console.log(`Tx Failed because expiry is in the past ${0}. Test Passed Successfully`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0})); }); it("Assign token balance to an address that can't receive funds", async() => { diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 25ce783a9..2766728a0 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -4,6 +4,7 @@ import { pk } from './helpers/testprivateKey'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); @@ -280,14 +281,7 @@ contract('GeneralPermissionManager', accounts => { it("Should successfully attach the General permission manager factory with the security token", async () => { let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); it("Should successfully attach the General permission manager factory with the security token", async () => { @@ -327,26 +321,12 @@ contract('GeneralPermissionManager', accounts => { it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async() => { let errorThrown = false; - try { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1}); - } catch(error) { - console.log(` tx revert -> msg.sender doesn't have permission`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1})); }); it("Should fail to provide the permission-- because delegate is not yet added", async() => { let errorThrown = false; - try { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); - } catch(error) { - console.log(` tx revert -> Delegate is not yet added`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner})); }); it("Should add the permission to the delegate", async() => { @@ -356,14 +336,7 @@ contract('GeneralPermissionManager', accounts => { it("Should fail to provide the permission", async() => { let errorThrown = false; - try { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1}); - } catch(error) { - console.log(` tx revert -> msg.sender doesn't have permission`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1})); }); it("Should check the permission", async() => { diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 36eccdbb0..f2a5c3fe5 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -4,6 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import {signData} from './helpers/signData'; import { pk } from './helpers/testprivateKey'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); @@ -317,14 +318,7 @@ contract('GeneralTransferManager', accounts => { it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { let errorThrown = false; - try { - await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Investor isn't present in the whitelist`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); }); it("Should Buy the tokens", async() => { @@ -357,28 +351,14 @@ contract('GeneralTransferManager', accounts => { it("Should fail in buying the token from the STO", async() => { let errorThrown = false; - try { - await I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Investor is restricted investor`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner })); }); it("Should fail in investing the money in STO -- expiry limit reached", async() => { let errorThrown = false; await increaseTime(duration.days(10)); - try { - await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Investor isn't present in the whitelist`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); }) }); @@ -387,14 +367,7 @@ contract('GeneralTransferManager', accounts => { it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { let errorThrown = false; - try { - await I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Investor isn't present in the whitelist`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner })); }); it("Should buy the tokens -- Failed due to incorrect signature input", async() => { @@ -409,8 +382,7 @@ contract('GeneralTransferManager', accounts => { const v = sig.v; let errorThrown = false; - try { - let tx = await I_GeneralTransferManager.modifyWhitelistSigned( + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( account_investor2, fromTime, toTime, @@ -424,13 +396,7 @@ contract('GeneralTransferManager', accounts => { { from: account_investor2, gas: 6000000 - }); - } catch(error) { - console.log(` tx revert -> Incorrect sig data`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); @@ -446,8 +412,7 @@ contract('GeneralTransferManager', accounts => { const v = sig.v; let errorThrown = false; - try { - let tx = await I_GeneralTransferManager.modifyWhitelistSigned( + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( account_investor2, fromTime, toTime, @@ -461,13 +426,7 @@ contract('GeneralTransferManager', accounts => { { from: account_investor2, gas: 6000000 - }); - } catch(error) { - console.log(` tx revert -> Incorrect sig data`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); @@ -484,8 +443,7 @@ contract('GeneralTransferManager', accounts => { const v = sig.v; let errorThrown = false; - try { - let tx = await I_GeneralTransferManager.modifyWhitelistSigned( + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( account_investor2, fromTime, toTime, @@ -499,13 +457,7 @@ contract('GeneralTransferManager', accounts => { { from: account_investor2, gas: 6000000 - }); - } catch(error) { - console.log(` tx revert -> Incorrect sig data`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); @@ -552,14 +504,7 @@ contract('GeneralTransferManager', accounts => { it("Should fail in changing the signing address", async() => { let errorThrown = false; - try { - await I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_investor4}); - } catch(error) { - console.log(` tx revert -> msg.sender is not token_owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_investor4})); }); it("Should get the permission", async() => { @@ -583,27 +528,13 @@ contract('GeneralTransferManager', accounts => { it("Should fail to pull fees as no budget set", async() => { let errorThrown = false; - try { - await I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> No budget set`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); }); it("Should set a budget for the GeneralTransferManager", async() => { await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), {from: token_owner}); let errorThrown = false; - try { - await I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath}); - } catch(error) { - console.log(` tx revert -> No balance on token`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), {from: token_owner}); }); @@ -611,40 +542,7 @@ contract('GeneralTransferManager', accounts => { it("Factory owner should pull fees - fails as not permissioned by issuer", async() => { let errorThrown = false; - try { - await I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate}); - } catch(error) { - console.log(` tx revert -> Incorrect permissions`.grey); - errorThrown = true; - ensureException(error); - } - }); - - it("Factory owner should pull fees", async() => { - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FEE_ADMIN", true, {from: token_owner}); - let balanceBefore = await I_PolyToken.balanceOf(account_polymath); - await I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate}); - let balanceAfter = await I_PolyToken.balanceOf(account_polymath); - assert.equal(balanceBefore.add(web3.utils.toWei('1','ether')).toNumber(), balanceAfter.toNumber(), "Fee is transferred"); - }); - - it("Should change the white list transfer variable", async() => { - let tx = await I_GeneralTransferManager.changeAllowAllWhitelistIssuances(true, {from : token_owner}); - assert.isTrue(tx.logs[0].args._allowAllWhitelistIssuances); - }); - - it("should failed in trasfering the tokens", async() => { - let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); - await I_GeneralTransferManager.pause({from: token_owner}); - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2','ether'), {from: account_investor2}); - } catch(error) { - console.log(` tx revert -> Transfer is paused`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate})); }); it("Should change the Issuance address", async() => { @@ -672,8 +570,7 @@ contract('GeneralTransferManager', accounts => { let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); let errorThrown = false; - try { - await I_GeneralTransferManager.modifyWhitelistMulti( + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], [toTime, toTime], @@ -683,13 +580,7 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - ); - } catch(error) { - console.log(` tx revert -> msg.sender is not allowed to modify the whitelist`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + )); }); it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { @@ -697,8 +588,7 @@ contract('GeneralTransferManager', accounts => { let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); let errorThrown = false; - try { - await I_GeneralTransferManager.modifyWhitelistMulti( + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime], [toTime, toTime], @@ -708,13 +598,7 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - ); - } catch(error) { - console.log(` tx revert -> Array length mismatch`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + )); }); it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { @@ -722,8 +606,7 @@ contract('GeneralTransferManager', accounts => { let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); let errorThrown = false; - try { - await I_GeneralTransferManager.modifyWhitelistMulti( + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], [toTime], @@ -733,13 +616,7 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - ); - } catch(error) { - console.log(` tx revert -> Array length mismatch`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + )); }); it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { @@ -747,8 +624,7 @@ contract('GeneralTransferManager', accounts => { let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); let errorThrown = false; - try { - await I_GeneralTransferManager.modifyWhitelistMulti( + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], [toTime, toTime], @@ -758,13 +634,7 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - ); - } catch(error) { - console.log(` tx revert -> Array length mismatch`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + )); }); it("Should successfully add the investors in whitelist", async() => { diff --git a/test/helpers/exceptions.js b/test/helpers/exceptions.js index c5fb6f45e..bdeda1472 100644 --- a/test/helpers/exceptions.js +++ b/test/helpers/exceptions.js @@ -1,44 +1,56 @@ const PREFIX = 'VM Exception while processing transaction: '; +const PREFIX2 = 'Returned error: VM Exception while processing transaction: '; -async function tryCatch(promise, message, reason) { +async function tryCatch(promise, message) { try { await promise; throw null; } catch (error) { assert(error, 'Expected an error but did not get one'); - assert( - error.message.startsWith(PREFIX + message), - "Expected an error starting with '" + + try { + assert( + error.message.startsWith(PREFIX + message), + "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead" - ); - console.log(reason); + ); + } catch (err) { + assert( + error.message.startsWith(PREFIX2 + message), + "Expected an error starting with '" + + PREFIX + + message + + "' but got '" + + error.message + + "' instead" + ); + } } } module.exports = { - catchRevert: async function(promise, reason) { - await tryCatch(promise, 'revert', reason); + catchRevert: async function(promise) { + await tryCatch(promise, 'revert'); }, - catchOutOfGas: async function(promise, reason) { - await tryCatch(promise, 'out of gas', reason); + catchOutOfGas: async function(promise) { + await tryCatch(promise, 'out of gas'); }, - catchInvalidJump: async function(promise, reason) { - await tryCatch(promise, 'invalid JUMP', reason); + catchInvalidJump: async function(promise) { + await tryCatch(promise, 'invalid JUMP'); }, - catchInvalidOpcode: async function(promise, reason) { - await tryCatch(promise, 'invalid opcode', reason); + catchInvalidOpcode: async function(promise) { + await tryCatch(promise, 'invalid opcode'); }, - catchStackOverflow: async function(promise, reason) { - await tryCatch(promise, 'stack overflow', reason); + catchStackOverflow: async function(promise) { + await tryCatch(promise, 'stack overflow'); }, - catchStackUnderflow: async function(promise, reason) { - await tryCatch(promise, 'stack underflow', reason); + catchStackUnderflow: async function(promise) { + await tryCatch(promise, 'stack underflow'); }, - catchStaticStateChange: async function(promise, reason) { - await tryCatch(promise, 'static state change', reason); + catchStaticStateChange: async function(promise) { + await tryCatch(promise, 'static state change'); } }; \ No newline at end of file diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 9036435f8..e01de1fa0 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -335,14 +336,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); it("Should successfully attach the General permission manager factory with the security token", async () => { @@ -370,14 +364,7 @@ contract('ManualApprovalTransferManager', accounts => { //function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { it("Cannot call verifyTransfer on the TM directly if _isTransfer == true", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid not from SecurityToken`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { from: token_owner })); }); @@ -423,38 +410,17 @@ contract('ManualApprovalTransferManager', accounts => { it("Should fail to add a manual approval because invalid _from address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.addManualApproval("", account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _from address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.addManualApproval("", account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual approval because invalid _to address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.addManualApproval(account_investor1, "", web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _to address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, "", web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual approval because invalid expiry time", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid expiry time`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { from: token_owner })); }); it("Add a manual approval for a 4th investor", async() => { @@ -463,26 +429,12 @@ contract('ManualApprovalTransferManager', accounts => { it("Should fail to revoke manual approval because invalid _from address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _from address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner })); }); it("Should fail to revoke manual approval because invalid _to address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, "", { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _to address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, "", { from: token_owner })); }); it("Should revoke manual approval", async() => { @@ -526,14 +478,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Check further transfers fail", async() => { let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> No remaining allowance`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); //Check that other transfers are still valid await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); @@ -542,38 +487,17 @@ contract('ManualApprovalTransferManager', accounts => { it("Should fail to add a manual block because invalid _from address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _from address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual block because invalid _to address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _to address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual block because invalid expiry time", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid expiry time`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner })); }); it("Add a manual block for a 2nd investor", async() => { @@ -582,39 +506,18 @@ contract('ManualApprovalTransferManager', accounts => { it("Check manual block causes failure", async() => { let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> Manual block`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); }); it("Should fail to revoke manual block because invalid _from address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.revokeManualBlocking("0x0", account_investor2, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _from address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking("0x0", account_investor2, { from: token_owner })); }); it("Should fail to revoke manual block because invalid _to address", async() => { let errorThrown = false; - try { - await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, "0x0", { from: token_owner }); - } catch(error) { - console.log(` tx revert -> invalid _to address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, "0x0", { from: token_owner })); }); it("Revoke manual block and check transfer works", async() => { @@ -629,14 +532,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Check manual block ignored after expiry", async() => { await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> Manual block`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); await increaseTime(1 + (24 * 60 * 60)); await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); }); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index a7ed18719..a62be5d15 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); @@ -215,14 +216,7 @@ contract('ModuleRegistry', accounts => { it("Should successfully update the registry contract address -- failed because of bad owner", async() => { let errorThrown = false; - try { - await I_MRProxied.updateFromRegistry({from: account_temp}); - } catch(error) { - console.log(` tx -> revert because of bad owner`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.updateFromRegistry({from: account_temp})); }); it("Should successfully update the registry contract addresses", async() => { @@ -260,14 +254,7 @@ contract('ModuleRegistry', accounts => { it("Should fail to register the module -- when registerModule is paused", async() => { await I_MRProxied.pause({from: account_polymath}); let errorThrown = false; - try { - let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_delegate}); - } catch(error) { - console.log(` tx -> revert because already registered modules are not allowed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_delegate})); await I_MRProxied.unpause({from: account_polymath}); }) @@ -286,27 +273,13 @@ contract('ModuleRegistry', accounts => { it("Should fail the register the module -- Already registered module", async() => { let errorThrown = false; - try { - let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert because already registered modules are not allowed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath})); }) it("Should fail in registering the module-- type = 0", async() => { I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); let errorThrown = false; - try { - await I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath }); - } catch(error) { - console.log(` tx revert -> Module factory of 0 type`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); }); }); @@ -314,14 +287,7 @@ contract('ModuleRegistry', accounts => { it("Should fail in calling the verify module. Because msg.sender should be account_polymath", async () => { let errorThrown = false; - try { - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp }); - } catch(error) { - console.log(` tx revert -> msg.sender should be account_polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); }); it("Should successfully verify the module -- true", async() => { @@ -356,14 +322,7 @@ contract('ModuleRegistry', accounts => { it("Should fail in verifying the module. Because the module is not registered", async() => { let errorThrown = false; - try { - await I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath }); - } catch(error) { - console.log(` tx revert -> Module is not registered`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); }); }) @@ -383,14 +342,7 @@ contract('ModuleRegistry', accounts => { endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); let errorThrown = false; - try { - const tx = await I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner}); - } catch(error) { - errorThrown = true; - console.log(` tx revert -> Module is un-verified`.grey); - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner})); }); it("Should fail to register module because custom modules not allowed", async() => { @@ -404,14 +356,7 @@ contract('ModuleRegistry', accounts => { let errorThrown = false; - try { - let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); - } catch(error) { - errorThrown = true; - console.log(` tx revert -> Module is un-verified`.grey); - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner })); }); @@ -459,14 +404,7 @@ contract('ModuleRegistry', accounts => { assert.equal(_lstVersion[1],1); let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); let errorThrown = false; - try { - let tx = await I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner }); - } catch(error) { - errorThrown = true; - console.log(` tx revert -> Incompatible with the lower bound of the Module factory`.grey); - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); await revertToSnapshot(id); }) @@ -489,14 +427,7 @@ contract('ModuleRegistry', accounts => { let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); let errorThrown = false; - try { - let tx = await I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner }); - } catch(error) { - errorThrown = true; - console.log(` tx revert -> Incompatible with the upper bound of the Module factory`.grey); - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); }); }); @@ -548,14 +479,7 @@ contract('ModuleRegistry', accounts => { it("Should fail if msg.sender not curator or owner", async() => { let errorThrown = false; - try { - await I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp }); - } catch(error) { - errorThrown = true; - console.log(` tx revert -> Module is un-verified`.grey); - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp })); }); it("Should successfully remove module and delete data if msg.sender is curator", async() => { @@ -612,14 +536,7 @@ contract('ModuleRegistry', accounts => { it("Should fail if module already removed", async() => { let errorThrown = false; - try { - await I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath }); - } catch(error) { - errorThrown = true; - console.log(` tx revert -> Module is un-verified`.grey); - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath })); }); }); @@ -642,14 +559,7 @@ contract('ModuleRegistry', accounts => { it("Should fail to pause if msg.sender is not owner", async() => { let errorThrown = false; - try { - await I_MRProxied.pause({ from: account_temp }); - } catch(error) { - console.log(` tx revert -> msg.sender should be account_polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.pause({ from: account_temp })); }); it("Should successfully pause the contract", async() => { @@ -660,14 +570,7 @@ contract('ModuleRegistry', accounts => { it("Should fail to unpause if msg.sender is not owner", async() => { let errorThrown = false; - try { - await I_MRProxied.unpause({ from: account_temp }); - } catch(error) { - console.log(` tx revert -> msg.sender should be account_polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_MRProxied.unpause({ from: account_temp })); }); it("Should successfully unpause the contract", async() => { diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 771330122..7659d33ac 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { setUpPolymathNetwork } from './helpers/createInstances'; +import { catchRevert } from './helpers/exceptions'; const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); @@ -251,14 +252,7 @@ contract('PercentageTransferManager', accounts => { it("Should successfully attach the PercentageTransferManagerr factory with the security token", async () => { let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); it("Should successfully attach the PercentageTransferManager factory with the security token", async () => { @@ -334,14 +328,7 @@ contract('PercentageTransferManager', accounts => { it("Should not be able to transfer between existing token holders over limit", async() => { let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> Too many holders`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 })); }); it("Modify holder percentage to 100", async() => { diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index 862885bcf..e43d87c94 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const PreSaleSTOFactory = artifacts.require('./PreSaleSTOFactory.sol'); @@ -255,14 +256,7 @@ contract('PreSaleSTO', accounts => { it("Should fail to launch the STO due to endTime is 0", async () => { let bytesSTO = encodeModuleCall(STOParameters, [0]); let errorThrown = false; - try { - const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Rate is ${0}. Test Passed Successfully`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); }); it("Should successfully attach the STO factory with the security token", async () => { @@ -302,14 +296,7 @@ contract('PreSaleSTO', accounts => { it("Should allocate the tokens -- failed due to investor not on whitelist", async () => { let errorThrown = false; - try { - await I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0); - } catch(error) { - console.log(` tx revert -> Investor is not on whitelist`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0)); }); it("Should Buy the tokens", async() => { @@ -349,14 +336,7 @@ contract('PreSaleSTO', accounts => { it("Should allocate the tokens -- failed due to msg.sender is not pre sale admin", async () => { let errorThrown = false; - try { - await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver }); - } catch(error) { - console.log(` tx revert -> msg.sender is not pre sale admin`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver })); }); it("Should allocate tokens to multiple investors", async() => { @@ -406,15 +386,7 @@ contract('PreSaleSTO', accounts => { it("Should failed at the time of buying the tokens -- Because STO has started", async() => { await increaseTime(duration.days(100)); // increased beyond the end time of the STO let errorThrown = false; - try { - // Fallback transaction - await I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, {from: account_issuer}); - } catch(error) { - console.log(` tx revert -> STO has started`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, {from: account_issuer})); }); }); @@ -427,14 +399,7 @@ contract('PreSaleSTO', accounts => { await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); let errorThrown = false; - try { - await I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner }); - } catch(error) { - console.log(` tx revert -> token contract address is 0 address`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); }); it("Should successfully reclaim POLY", async() => { diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 8c5c611a7..44d830765 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -701,14 +701,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should successfully generate the custom token", async() => { // Fulfilling the TickerStatus.NN condition // let errorThrown = false; - // try { - // await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); - // } catch(error) { - // console.log(` tx revert -> because ticker not registered`.grey); - // errorThrown = true; - // ensureException(error); - // } - // assert.ok(errorThrown, message); + // await catchRevert(I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath})); // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); // await increaseTime(duration.days(1)); let tx = await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); diff --git a/test/o_security_token.js b/test/o_security_token.js index 1217c6c22..594f7d542 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); @@ -297,14 +298,7 @@ contract('SecurityToken', accounts => { gas: 6000000 }); assert.equal(tx.logs[0].args._investor, account_affiliate1, "Failed in adding the investor in whitelist"); - try { - await I_SecurityToken.mint(account_investor1, (100 * Math.pow(10, 18)), {from: account_delegate}); - } catch(error) { - console.log(` tx revert -> Mint only be called by the owner of the SecurityToken`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.mint(account_investor1, (100 * Math.pow(10, 18)), {from: account_delegate})); }); it("Should mint the tokens before attaching the STO", async() => { @@ -331,26 +325,12 @@ contract('SecurityToken', accounts => { }); assert.equal(tx.logs[0].args._investor, account_affiliate2, "Failed in adding the investor in whitelist"); - try { - await I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18)), (110 * Math.pow(10, 18))], {from: account_delegate, gas: 500000}); - } catch(error) { - console.log(` tx revert -> Mint only be called by the owner of the SecurityToken`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18)), (110 * Math.pow(10, 18))], {from: account_delegate, gas: 500000})); }); it("Should mintMulti", async() => { let errorThrown = false; - try { - await I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18))], {from: token_owner, gas: 500000}); - } catch(error) { - console.log(` tx revert -> Array length are un-equal`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18))], {from: token_owner, gas: 500000})); }) it("Should mint the tokens for multiple afiliated investors before attaching the STO", async() => { @@ -363,78 +343,36 @@ contract('SecurityToken', accounts => { it("Should finish the minting -- fail because feature is not activated", async() => { let errorThrown = false; - try { - await I_SecurityToken.freezeMinting({from: token_owner}); - } catch(error) { - console.log(` tx revert -> freezeMinting cannot be called before activated by polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.freezeMinting({from: token_owner})); }); 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: token_owner}); - } catch(error) { - console.log(` tx revert -> allowFreezeMinting must be called by polymath`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: token_owner})); }); it("Should finish the minting -- successfully activate the feature", async() => { 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); + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", false, {from: account_polymath})); 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); + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_polymath})); }); it("Should finish the minting -- fail because msg.sender is not the owner", async() => { let errorThrown = false; - try { - await I_SecurityToken.freezeMinting({from: account_temp}); - } catch(error) { - console.log(` tx revert -> freezeMinting only be called by the owner of the SecurityToken`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.freezeMinting({from: account_temp})); }); it("Should finish minting & restrict the further minting", 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 catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); await revertToSnapshot(id); }); @@ -443,14 +381,7 @@ contract('SecurityToken', accounts => { endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); let errorThrown = false; - try { - let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - } catch (error) { - console.log(` tx revert -> not enough poly in contract`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to attach the STO factory because max cost too small", async () => { @@ -460,14 +391,7 @@ contract('SecurityToken', accounts => { await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: token_owner}); let errorThrown = false; - try { - let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner }); - } catch (error) { - console.log(` tx revert -> max cost too small`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner })); }); it("Should successfully attach the STO factory with the security token", async () => { @@ -495,14 +419,7 @@ contract('SecurityToken', accounts => { 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 catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); await revertToSnapshot(id); }); @@ -546,14 +463,7 @@ contract('SecurityToken', accounts => { it("Should fail in updating the token details", async() => { let errorThrown = false; - try { - let log = await I_SecurityToken.updateTokenDetails("new token details", {from: account_delegate}); - } catch (error) { - console.log(` tx revert -> msg.sender should be the owner of the token`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.updateTokenDetails("new token details", {from: account_delegate})); }); it("Should update the token details", async() => { @@ -563,38 +473,17 @@ contract('SecurityToken', accounts => { it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async() => { let errorThrown = false; - try { - let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp }); - } catch (error) { - console.log(`Test Case passed by restricting the unknown account to call removeModule of the securityToken`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp })); }); it("Should fail to remove the module - module not archived", async() => { let errorThrown = false; - try { - let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner }); - } catch (error) { - console.log(` tx -> Failed because address doesn't exist`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner })); }) it("Should fail to remove the module - incorrect address", async() => { let errorThrown = false; - try { - let tx = await I_SecurityToken.removeModule(0, { from : token_owner }); - } catch (error) { - console.log(` tx -> Failed because address doesn't exist`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.removeModule(0, { from : token_owner })); }) it("Should successfully remove the general transfer manager module from the securityToken", async() => { @@ -645,27 +534,13 @@ contract('SecurityToken', accounts => { it("Should fail to mint tokens while GTM unarchived", async () => { let errorThrown = false; - try { - await I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); - } catch(error) { - console.log(` tx -> Failed because GTM`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); }); it("Should change the budget of the module - fail incorrect address", async() => { let errorThrown = false; - try { - let tx = await I_SecurityToken.changeModuleBudget(0, (100 * Math.pow(10, 18)),{ from : token_owner}); - } catch(error) { - console.log(` tx -> Failed because address is 0`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.changeModuleBudget(0, (100 * Math.pow(10, 18)),{ from : token_owner})); }); @@ -728,14 +603,7 @@ contract('SecurityToken', accounts => { it("Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2", async() => { let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1}); - } catch(error) { - console.log(` tx revert -> Investor 2 is not in the whitelist`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1})); }); it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { @@ -744,14 +612,7 @@ contract('SecurityToken', accounts => { await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: token_owner}); let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - try { - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp }); - } catch (error) { - console.log(`${account_temp} doesn't have permissions to register the delegate`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); }); it("Should provide the permission to the delegate to change the transfer bools", async () => { @@ -766,14 +627,7 @@ contract('SecurityToken', accounts => { it("Should fail to activate the bool allowAllTransfer", async() => { let errorThrown = false; - try { - let tx = await I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_temp }); - } catch (error) { - console.log(`${account_temp} doesn't have permissions to activate the bool allowAllTransfer`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_temp })); }); it("Should activate the bool allowAllTransfer", async() => { @@ -786,26 +640,12 @@ contract('SecurityToken', accounts => { it("Should fail to send tokens with the wrong granularity", async() => { let errorThrown = false; - try { - await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1}); - } catch (error) { - console.log(' tx revert -> Incorrect token granularity - expected'.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1})); }); it("Should adjust granularity", async() => { let errorThrown = false; - try { - await I_SecurityToken.changeGranularity(0, {from: token_owner }); - } catch(error) { - console.log(' tx revert -> Incorrect token granularity - expected'.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.changeGranularity(0, {from: token_owner })); }); it("Should adjust granularity", async() => { @@ -895,14 +735,7 @@ contract('SecurityToken', accounts => { it("Should Fail in trasferring from whitelist investor1 to non-whitelist investor", async() => { let errorThrown = false; - try { - await I_SecurityToken.transfer(account_temp, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000}); - } catch(error) { - console.log(`non-whitelist investor is not allowed`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_temp, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000})); await revertToSnapshot(ID_snap); }); @@ -972,19 +805,12 @@ contract('SecurityToken', accounts => { let id = await takeSnapshot(); await I_SecurityToken.freezeMinting({from: token_owner}); let errorThrown = false; - try { - await web3.eth.sendTransaction({ + await catchRevert(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); }); @@ -1005,21 +831,12 @@ contract('SecurityToken', accounts => { it("should account_temp fail in buying the token", async() => { let errorThrown = false; - try { - // Fallback transaction - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, gas: 2100000, value: web3.utils.toWei('1', 'ether') - }); - - } catch (error) { - console.log(`non-whitelist investor is not allowed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); it("Should freeze the transfers", async() => { @@ -1029,14 +846,7 @@ contract('SecurityToken', accounts => { it("Should fail to freeze the transfers", async() => { let errorThrown = false; - try { - await I_SecurityToken.freezeTransfers({from: token_owner}); - } catch(error) { - console.log(` tx -> Revert because freeze is already true`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.freezeTransfers({from: token_owner})); }); it("Should fail in buying to tokens", async() => { @@ -1054,35 +864,19 @@ contract('SecurityToken', accounts => { assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); let errorThrown = false; - try { - // Fallback transaction - await web3.eth.sendTransaction({ + await catchRevert(web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, gas: 2100000, value: web3.utils.toWei('1', 'ether') - }); - - } catch (error) { - console.log(`Because all transfers get freezed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + })); }); it("Should fail in trasfering the tokens from one user to another", async() => { await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); console.log(await I_SecurityToken.balanceOf(account_investor1)); let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp}); - } catch(error) { - console.log(' tx revert -> All transfers are at hold'.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp})); }); it("Should unfreeze all the transfers", async() => { @@ -1092,14 +886,7 @@ contract('SecurityToken', accounts => { it("Should freeze the transfers", async() => { let errorThrown = false; - try { - await I_SecurityToken.unfreezeTransfers({from: token_owner}); - } catch(error) { - console.log(` tx -> Revert because freeze is already false`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.unfreezeTransfers({from: token_owner})); }); it("Should able to transfers the tokens from one user to another", async() => { @@ -1120,14 +907,7 @@ contract('SecurityToken', accounts => { }); it("Should fail to set controller status because msg.sender not owner", async() => { let errorThrown = false; - try { - await I_SecurityToken.setController(account_controller, {from: account_controller}); - } catch (error) { - console.log(` tx revert -> msg.sender not owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.setController(account_controller, {from: account_controller})); }); it("Should successfully set controller", async() => { @@ -1159,28 +939,14 @@ contract('SecurityToken', accounts => { await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); let currentInvestorCount = await I_SecurityToken.investorCount(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); - try { - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", { from: account_controller }); - } catch(error) { - console.log(` tx revert -> value is greater than its current balance`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", { from: account_controller })); }); it("Should force burn the tokens - wrong caller", async ()=> { let errorThrown = false; await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); let currentInvestorCount = await I_SecurityToken.investorCount(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); - try { - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: token_owner }); - } catch(error) { - console.log(` tx revert -> not owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: token_owner })); }); it("Should burn the tokens", async ()=> { @@ -1210,14 +976,7 @@ contract('SecurityToken', accounts => { it("Should check the balance of investor at checkpoint", async() => { let errorThrown = false; - try { - await I_SecurityToken.balanceOfAt(account_investor1, 5); - } catch(error) { - console.log(` tx -> Revert checkpoint ID is greator than current checkpoint`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); }); it("Should check the balance of investor at checkpoint", async() => { @@ -1230,14 +989,7 @@ contract('SecurityToken', accounts => { it("Should successfully withdraw the poly", async() => { let errorThrown = false; - try { - await I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: account_temp}); - } catch (error) { - console.log(` tx revert -> withdrawPoly function can only be called by the owner of the seucrity token`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: account_temp})); }) it("Should successfully withdraw the poly", async() => { @@ -1249,14 +1001,7 @@ contract('SecurityToken', accounts => { it("Should successfully withdraw the poly", async() => { let errorThrown = false; - try { - await I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), {from: token_owner}); - } catch (error) { - console.log(` tx revert -> token doesn't have any POLY`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), {from: token_owner})); }); }); @@ -1264,38 +1009,17 @@ contract('SecurityToken', accounts => { it("Should fail to forceTransfer because not approved controller", async() => { let errorThrown1 = false; - try { - await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_investor1}); - } catch (error) { - console.log(` tx revert -> not approved controller`.grey); - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, message); + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_investor1})); }); it("Should fail to forceTransfer because insufficient balance", async() => { let errorThrown = false; - try { - await I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); - } catch (error) { - console.log(` tx revert -> insufficient balance`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); }); it("Should fail to forceTransfer because recipient is zero address", async() => { let errorThrown = false; - try { - await I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); - } catch (error) { - console.log(` tx revert -> recipient is zero address`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); }); it("Should successfully forceTransfer", async() => { @@ -1332,26 +1056,12 @@ contract('SecurityToken', accounts => { it("Should fail to freeze controller functionality because not owner", async() => { let errorThrown = false; - try { - await I_SecurityToken.disableController({from: account_investor1}); - } catch (error) { - console.log(` tx revert -> not owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.disableController({from: account_investor1})); }); it("Should fail to freeze controller functionality because disableControllerAllowed not activated", async() => { let errorThrown = false; - try { - await I_SecurityToken.disableController({from: token_owner}); - } catch (error) { - console.log(` tx revert -> disableControllerAllowed not activated`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.disableController({from: token_owner})); }); it("Should successfully freeze controller functionality", async() => { @@ -1370,38 +1080,17 @@ contract('SecurityToken', accounts => { it("Should fail to freeze controller functionality because already frozen", async() => { let errorThrown = false; - try { - await I_SecurityToken.disableController({from: token_owner}); - } catch (error) { - console.log(` tx revert -> already frozen`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.disableController({from: token_owner})); }); it("Should fail to set controller because controller functionality frozen", async() => { let errorThrown = false; - try { - await I_SecurityToken.setController(account_controller, {from: token_owner}); - } catch (error) { - console.log(` tx revert -> msg.sender not owner`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.setController(account_controller, {from: token_owner})); }); it("Should fail to forceTransfer because controller functionality frozen", async() => { let errorThrown = false; - try { - await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); - } catch (error) { - console.log(` tx revert -> recipient is zero address`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); }); }); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 1acc0ef7d..c0b42a7fb 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); @@ -544,13 +545,7 @@ contract('USDTieredSTO', accounts => { for (var i = 0; i < config.length; i++) { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); let errorThrown = false; - try { - await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, MESSAGE); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); } }); @@ -561,13 +556,7 @@ contract('USDTieredSTO', accounts => { let config = [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let errorThrown = false; - try { - await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, MESSAGE); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); it("Should fail because Zero address is not permitted for wallet", async() => { @@ -577,13 +566,7 @@ contract('USDTieredSTO', accounts => { let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], wallet, _reserveWallet[stoId], _usdToken[stoId]]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let errorThrown = false; - try { - await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, MESSAGE); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); it("Should fail because Zero address is not permitted for reserveWallet", async() => { @@ -593,1390 +576,148 @@ contract('USDTieredSTO', accounts => { let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], reserveWallet]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let errorThrown = false; - try { - await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, MESSAGE); - }); - - it("Should fail because end time before start time", async() => { - let stoId = 0; - - let startTime = latestTime() + duration.days(35); - let endTime = latestTime() + duration.days(1); - let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let errorThrown = false; - try { - await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, MESSAGE); - }); - - it("Should fail because start time is in the past", async() => { - let stoId = 0; - - let startTime = latestTime() - duration.days(35); - let endTime = startTime + duration.days(50); - let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let errorThrown = false; - try { - await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, MESSAGE); - }); - }); - - describe("Test modifying configuration", async() => { - - it("Should successfully change config before startTime - funding", async() => { - let stoId = 3; - await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),false,"STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyFunding([1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),false,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - - - }); - - it("Should successfully change config before startTime - limits and tiers, times, addresses", async() => { - let stoId = 3; - - await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1*10**18), BigNumber(15*10**18), { from: ISSUER }); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(),BigNumber(1*10**18).toNumber(),"STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER }); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(),BigNumber(13*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); - - let tempTime1 = latestTime() + duration.days(0.1); - let tempTime2 = latestTime() + duration.days(0.2); - - await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(),tempTime1,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(),tempTime2,"STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", "0x0000000000000000000000000000000000000000", { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(),"0x0000000000000000000000000400000000000000","STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(),"0x0000000000000000000003000000000000000000","STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(),"0x0000000000000000000000000000000000000000","STO Configuration doesn't set as expected"); - }); - - it("Should fail to change config after endTime", async() => { - let stoId = 3; - - let snapId = await takeSnapshot(); - await increaseTime(duration.days(1)); - - let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); - - let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15*10**18), BigNumber(1*10**18), { from: ISSUER }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); - - let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, MESSAGE); - - let tempTime1 = latestTime(); - let tempTime2 = latestTime() + duration.days(3); - - let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, MESSAGE); - - let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", I_DaiToken.address, { from: ISSUER }); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, MESSAGE); - - await revertToSnapshot(snapId); - }); - }); - - describe("Test buying failure conditions", async() => { - - it("should fail if before STO start time", async() => { - let stoId = 0; - let snapId = await takeSnapshot(); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); - - // Whitelist - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - - // // Advance time to after STO start - // await increaseTime(duration.days(3)); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - // NONACCREDITED ETH - let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, 'NONACCREDITED ETH investment succeeded when it should not'); - - // NONACCREDITED POLY - let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, 'NONACCREDITED POLY investment succeeded when it should not'); - - // NONACCREDITED DAI - let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, 'NONACCREDITED POLY investment succeeded when it should not'); - - // ACCREDITED ETH - let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, 'ACCREDITED ETH investment succeeded when it should not'); - - // ACCREDITED POLY - let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, 'ACCREDITED POLY investment succeeded when it should not'); - - // ACCREDITED DAI - let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, 'ACCREDITED POLY investment succeeded when it should not'); - - await revertToSnapshot(snapId); - }); - - it("should fail if not whitelisted", async() => { - let stoId = 0; - let snapId = await takeSnapshot(); - - // // Whitelist - // let fromTime = latestTime(); - // let toTime = latestTime() + duration.days(15); - // let expiryTime = toTime + duration.days(100); - // let whitelisted = true; - // - // await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - // await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - - // Advance time to after STO start - await increaseTime(duration.days(3)); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - // NONACCREDITED ETH - let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, 'NONACCREDITED ETH investment succeeded when it should not'); - - // NONACCREDITED POLY - let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, 'NONACCREDITED POLY investment succeeded when it should not'); - - // NONACCREDITED DAI - let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, 'NONACCREDITED DAI investment succeeded when it should not'); - - // ACCREDITED ETH - let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, 'ACCREDITED ETH investment succeeded when it should not'); - - // ACCREDITED POLY - let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, 'ACCREDITED POLY investment succeeded when it should not'); - - // ACCREDITED DAI - let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, 'ACCREDITED DAI investment succeeded when it should not'); - - await revertToSnapshot(snapId); - }); - - it("should fail if minimumInvestmentUSD not met", async() => { - let stoId = 0; - let tierId = 0; - let snapId = await takeSnapshot(); - - // Whitelist - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - - // Advance time to after STO start - await increaseTime(duration.days(3)); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - let investment_USD = BigNumber(2).mul(10**18); - let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); - let investment_POLY = await convert(stoId, tierId, false, "USD", "POLY", investment_USD); - let investment_DAI = investment_USD; - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - - - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - // NONACCREDITED ETH - let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, 'NONACCREDITED ETH investment succeeded when it should not'); - - // NONACCREDITED POLY - let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, 'NONACCREDITED POLY investment succeeded when it should not'); - - // NONACCREDITED DAI - let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, 'NONACCREDITED DAI investment succeeded when it should not'); - - // ACCREDITED ETH - let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, 'ACCREDITED ETH investment succeeded when it should not'); - - // ACCREDITED POLY - let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, 'ACCREDITED POLY investment succeeded when it should not'); - - // ACCREDITED DAI - let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, 'ACCREDITED DAI investment succeeded when it should not'); - - await revertToSnapshot(snapId); - }); - - it("should successfully pause the STO and make investments fail, then unpause and succeed", async() => { - let stoId = 0; - let snapId = await takeSnapshot(); - - // Whitelist - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - - // Advance time to after STO start - await increaseTime(duration.days(3)); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - // Pause the STO - await I_USDTieredSTO_Array[stoId].pause({ from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), true, 'STO did not pause successfully'); - - // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - // NONACCREDITED ETH - let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, 'NONACCREDITED ETH investment succeeded when it should not'); - - // NONACCREDITED POLY - let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, 'NONACCREDITED POLY investment succeeded when it should not'); - - // NONACCREDITED DAI - let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, 'NONACCREDITED DAI investment succeeded when it should not'); - - // ACCREDITED ETH - let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, 'ACCREDITED ETH investment succeeded when it should not'); - - // ACCREDITED POLY - let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, 'ACCREDITED POLY investment succeeded when it should not'); - - - // ACCREDITED DAI - let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, 'ACCREDITED DAI investment succeeded when it should not'); - - // Unpause the STO - await I_USDTieredSTO_Array[stoId].unpause({ from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), false, 'STO did not unpause successfully'); - - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); - - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); - - await revertToSnapshot(snapId); - }); - - it("should fail if after STO end time", async() => { - let stoId = 3; - let snapId = await takeSnapshot(); - - // Whitelist - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - - // Advance time to after STO end - await increaseTime(duration.days(3)); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - - // NONACCREDITED ETH - let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, 'NONACCREDITED ETH investment succeeded when it should not'); - - // NONACCREDITED POLY - let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, 'NONACCREDITED POLY investment succeeded when it should not'); - - // NONACCREDITED DAI - let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, 'NONACCREDITED DAI investment succeeded when it should not'); - - // ACCREDITED ETH - let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, 'ACCREDITED ETH investment succeeded when it should not'); - - // ACCREDITED POLY - let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, 'ACCREDITED POLY investment succeeded when it should not'); - - // ACCREDITED DAI - let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, 'ACCREDITED DAI investment succeeded when it should not'); - - await revertToSnapshot(snapId); - }); - - it("should fail if finalized", async() => { - let stoId = 0; - let snapId = await takeSnapshot(); - - // Whitelist - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(RESERVEWALLET, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - - // Advance time to after STO start - await increaseTime(duration.days(3)); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - // Finalize STO - await I_USDTieredSTO_Array[stoId].finalize({ from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].isFinalized.call(), true, "STO has not been finalized"); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); - - // Attempt to call function again - let errorThrown = false; - try { - await I_USDTieredSTO_Array[stoId].finalize({ from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, 'STO was finalized a second time'); - - // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - // NONACCREDITED ETH - let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, 'NONACCREDITED ETH investment succeeded when it should not'); - - // NONACCREDITED POLY - let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, 'NONACCREDITED POLY investment succeeded when it should not'); - - // NONACCREDITED DAI - let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, 'NONACCREDITED DAI investment succeeded when it should not'); - - // ACCREDITED ETH - let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, 'ACCREDITED ETH investment succeeded when it should not'); - - // ACCREDITED POLY - let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, 'ACCREDITED POLY investment succeeded when it should not'); - - // ACCREDITED DAI - let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, 'ACCREDITED DAI investment succeeded when it should not'); - - await revertToSnapshot(snapId); - }); - }); - - describe("Prep STO", async() => { - - it("should jump forward to after STO start", async() => { - let stoId = 0; - await increaseTime(duration.days(3)); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),true,"STO is not showing correct status"); - }); - - it("should whitelist ACCREDITED1 and NONACCREDITED1", async() => { - let stoId = 0; - - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - const tx1 = await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - assert.equal(tx1.logs[0].args._investor, NONACCREDITED1, "Failed in adding the investor in whitelist"); - const tx2 = await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - assert.equal(tx2.logs[0].args._investor, ACCREDITED1, "Failed in adding the investor in whitelist"); - }); - - it("should successfully modify accredited addresses for first STO", async() => { - let stoId = 0; - - let status1 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - assert.equal(status1, false, "Initial accreditation is set to true"); - - await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1], [true], { from: ISSUER }); - let status2 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - assert.equal(status2, true, "Failed to set single address"); - - await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [false, true], { from: ISSUER }); - let status3 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - assert.equal(status3, false, "Failed to set multiple addresses"); - let status4 = await I_USDTieredSTO_Array[stoId].accredited.call(ACCREDITED1); - assert.equal(status4, true, "Failed to set multiple addresses"); - - let errorThrown = false; - try { - await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [true], { from: ISSUER }); - } catch(error) { - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, "Set accreditation despite input array of different size"); - }); - - it("should successfully modify accredited addresses for second STO", async() => { - let stoId = 1; - - await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [false, true], { from: ISSUER }); - let status1 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - let status2 = await I_USDTieredSTO_Array[stoId].accredited.call(ACCREDITED1); - assert.equal(status1, false, "Failed to set multiple address"); - assert.equal(status2, true, "Failed to set multiple address"); - }); - }); - - describe("Buy Tokens with no discount", async() => { - - it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async() => { - let stoId = 0; - let tierId = 0; - - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await web3.eth.sendTransaction({ from: NONACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), "Raised USD not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional checks on getters - assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), investment_Token.toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), investment_Token.toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), investment_Token.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), 0, "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), investment_USD.toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), investment_ETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), 0, "investorInvestedPOLY not changed as expected"); - }); - - it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async() => { - let stoId = 0; - let tierId = 0; - - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised DAI not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async() => { - let stoId = 0; - let tierId = 0; - - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should successfully buy using buyWithUSD at tier 0 for NONACCREDITED1", async() => { - let stoId = 0; - let tierId = 0; - - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - let investment_DAI = investment_USD; - - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_InvestorDAIBal = await I_DaiToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - // Buy With DAI - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithUSD: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_InvestorDAIBal = await I_DaiToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), "Investor DAI Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - assert.equal(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), "Wallet DAI Balance not changed as expected"); - }); - - it("should successfully buy using fallback at tier 0 for ACCREDITED1", async() => { - let stoId = 0; - let tierId = 0; - - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await web3.eth.sendTransaction({ from: ACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async() => { - let stoId = 0; - let tierId = 0; - - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); - it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async() => { + it("Should fail because end time before start time", async() => { let stoId = 0; - let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + let startTime = latestTime() + duration.days(35); + let endTime = latestTime() + duration.days(1); + let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + it("Should fail because start time is in the past", async() => { + let stoId = 0; - // Additional checks on getters - let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_getTokensMinted = await I_USDTieredSTO_Array[stoId].getTokensMinted(); - let init_getTokensSoldForETH = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH); - let init_getTokensSoldForPOLY = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY); - let init_investorInvestedUSD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1); - let init_investorInvestedETH = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH); - let init_investorInvestedPOLY = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY); + let startTime = latestTime() - duration.days(35); + let endTime = startTime + duration.days(50); + let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + }); - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + describe("Test modifying configuration", async() => { - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + it("Should successfully change config before startTime - funding", async() => { + let stoId = 3; + await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),false,"STO Configuration doesn't set as expected"); - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + await I_USDTieredSTO_Array[stoId].modifyFunding([1], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),false,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + await I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - // Additional checks on getters - assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), init_getTokensSold.add(investment_Token).toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), init_getTokensMinted.add(investment_Token).toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), init_getTokensSoldForETH.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), init_getTokensSoldForPOLY.add(investment_Token).toNumber(), "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), init_investorInvestedUSD.add(investment_USD).toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), init_investorInvestedETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), init_investorInvestedPOLY.add(investment_POLY).toNumber(), "investorInvestedPOLY not changed as expected"); - }); - it("should successfully modify NONACCREDITED cap for NONACCREDITED1", async() => { - let stoId = 0; - let tierId = 0; - console.log("Current investment: " + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber()); - await I_USDTieredSTO_Array[stoId].changeNonAccreditedLimit([NONACCREDITED1], [_nonAccreditedLimitUSD[stoId].div(2)], {from: ISSUER}); - console.log("Current limit: " + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1)).toNumber()); }); - it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async() => { - let stoId = 0; - let tierId = 0; + it("Should successfully change config before startTime - limits and tiers, times, addresses", async() => { + let stoId = 3; - let investment_USD = (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1));//_nonAccreditedLimitUSD[stoId]; - let investment_Token = await convert(stoId, tierId, false, "USD", "TOKEN", investment_USD); - let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); - let investment_POLY = await convert(stoId, tierId, false, "USD", "POLY", investment_USD); + await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1*10**18), BigNumber(15*10**18), { from: ISSUER }); + assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(),BigNumber(1*10**18).toNumber(),"STO Configuration doesn't set as expected"); - let refund_USD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); - let refund_Token = await convert(stoId, tierId, false, "USD", "TOKEN", refund_USD); - let refund_ETH = await convert(stoId, tierId, false, "USD", "ETH", refund_USD); - let refund_POLY = await convert(stoId, tierId, false, "USD", "POLY", refund_USD); + await I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER }); + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(),BigNumber(13*10**18).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); - console.log("Expected refund in tokens: " + refund_Token.toNumber()); + let tempTime1 = latestTime() + duration.days(0.1); + let tempTime2 = latestTime() + duration.days(0.2); - let snap = await takeSnapshot(); + await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(),tempTime1,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(),tempTime2,"STO Configuration doesn't set as expected"); - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + await I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", "0x0000000000000000000000000000000000000000", { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(),"0x0000000000000000000000000400000000000000","STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(),"0x0000000000000000000003000000000000000000","STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(),"0x0000000000000000000000000000000000000000","STO Configuration doesn't set as expected"); + }); - // Buy with ETH - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + it("Should fail to change config after endTime", async() => { + let stoId = 3; - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let snapId = await takeSnapshot(); + await increaseTime(duration.days(1)); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).add(refund_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).sub(refund_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).sub(refund_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER })); - await revertToSnapshot(snap); + let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15*10**18), BigNumber(1*10**18), { from: ISSUER })); - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER })); - init_TokenSupply = await I_SecurityToken.totalSupply(); - init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let tempTime1 = latestTime(); + let tempTime2 = latestTime() + duration.days(3); - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER })); - final_TokenSupply = await I_SecurityToken.totalSupply(); - final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let errorThrown5 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", I_DaiToken.address, { from: ISSUER })); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).add(refund_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).sub(refund_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).sub(refund_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + await revertToSnapshot(snapId); }); + }); - it("should fail and revert when NONACCREDITED cap reached", async() => { + describe("Test buying failure conditions", async() => { + + it("should fail if before STO start time", async() => { let stoId = 0; - let tierId = 0; + let snapId = await takeSnapshot(); - let investment_Token = BigNumber(50).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + + // Whitelist + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + + // // Advance time to after STO start + // await increaseTime(duration.days(3)); + + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + // Prep for investments + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1, gasPrice: GAS_PRICE}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - // Buy with ETH NONACCREDITED + // NONACCREDITED ETH let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); }); it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { @@ -2004,23 +745,11 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); @@ -2028,23 +757,11 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); @@ -2415,63 +1132,27 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with DAI NONACCREDITED let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Buy with DAI ACCREDITED let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE })); }); it("should fail and revert when all tiers sold out despite oracle price change", async() => { @@ -2501,43 +1182,19 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); @@ -2545,43 +1202,19 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED let errorThrown7 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown7 = true; - ensureException(error); - } - assert.ok(errorThrown7, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED let errorThrown8 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown8 = true; - ensureException(error); - } - assert.ok(errorThrown8, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); @@ -3006,23 +1639,11 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); }); it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { @@ -3052,23 +1673,11 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); @@ -3076,23 +1685,11 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); @@ -3276,43 +1873,19 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); }); it("should fail and revert when all tiers sold out despite oracle price change", async() => { @@ -3344,43 +1917,19 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown1 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown1 = true; - ensureException(error); - } - assert.ok(errorThrown1, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown2 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown2 = true; - ensureException(error); - } - assert.ok(errorThrown2, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED let errorThrown3 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown3 = true; - ensureException(error); - } - assert.ok(errorThrown3, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED let errorThrown4 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown4 = true; - ensureException(error); - } - assert.ok(errorThrown4, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); @@ -3388,43 +1937,19 @@ contract('USDTieredSTO', accounts => { // Buy with ETH NONACCREDITED let errorThrown5 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown5 = true; - ensureException(error); - } - assert.ok(errorThrown5, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED let errorThrown6 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown6 = true; - ensureException(error); - } - assert.ok(errorThrown6, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED let errorThrown7 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown7 = true; - ensureException(error); - } - assert.ok(errorThrown7, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED let errorThrown8 = false; - try { - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown8 = true; - ensureException(error); - } - assert.ok(errorThrown8, MESSAGE); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index cd00ccb8d..36fa7920d 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); @@ -620,22 +621,7 @@ contract('USDTieredSTO Sim', accounts => { let investment_DAI = BigNumber(10*10**18); // 10 USD = DAI DAI let errorThrown = false; - try { - if (isPoly) { - await I_PolyToken.getTokens(investment_POLY, _investor); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: _investor}); - await I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE }); - } else if (isDAI) { - await I_DaiToken.getTokens(investment_DAI, _investor); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: _investor}); - await I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE }); - } else await I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE }); - } catch(error) { - errorThrown = true; - console.log(`Purchase failed as expected: ${_investor}`.yellow); - ensureException(error); - } - assert.ok(errorThrown, MESSAGE); + await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); } async function processInvestment(_investor, investment_Token, investment_USD, investment_POLY, investment_DAI, investment_ETH, isPoly, isDai, log_remaining, Tokens_total, Tokens_discount, tokensSold) { diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 2666f7158..42357b7d8 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -1,5 +1,6 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import { encodeProxyCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); @@ -206,74 +207,32 @@ contract ("SecurityTokenRegistryProxy", accounts => { it("Should upgrade the version and implementation address -- fail bad owner", async() => { let errorThrown = false; I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({from: account_polymath}); - try { - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_temp}); - } catch(error) { - console.log(` tx -> revert bad owner of the proxy contract`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_temp})); }); it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { let errorThrown = false; - try { - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert Implementaion address should be a contract address`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { let errorThrown = false; - try { - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert Implemenation address should not be 0x`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { let errorThrown = false; - try { - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistry.address, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert Implemenation address should not be the same address`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistry.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { let errorThrown = false; - try { - await I_SecurityTokenRegistryProxy.upgradeTo("1.0.0", I_SecurityTokenRegistryMock.address, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert same version as previous is not allowed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.0.0", I_SecurityTokenRegistryMock.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { let errorThrown = false; - try { - await I_SecurityTokenRegistryProxy.upgradeTo("", I_SecurityTokenRegistryMock.address, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert empty version string is not allowed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("", I_SecurityTokenRegistryMock.address, {from: account_polymath})); }); it("Should upgrade the version and the implementation address successfully", async() => { @@ -306,26 +265,12 @@ contract ("SecurityTokenRegistryProxy", accounts => { it("Should change the ownership of the contract -- because of bad owner", async()=> { let errorThrown = false; - try { - await I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp}); - } catch(error) { - console.log(` tx -> revert because of bad owner`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); }); it("Should change the ownership of the contract -- new address should not be 0x", async()=> { let errorThrown = false; - try { - await I_SecurityTokenRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert because new owner address should not be 0x`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); }); it("Should change the ownership of the contract", async()=> { diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index b6fcc5db5..b3a674f7a 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -1,5 +1,6 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import { encodeProxyCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); @@ -200,74 +201,32 @@ contract ("ModuleRegistryProxy", accounts => { it("Should upgrade the version and implementation address -- fail bad owner", async() => { let errorThrown = false; I_MockModuleRegistry = await MockModuleRegistry.new({from: account_polymath}); - try { - await I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_temp}); - } catch(error) { - console.log(` tx -> revert bad owner of the proxy contract`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_temp})); }); it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { let errorThrown = false; - try { - await I_ModuleRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert Implementaion address should be a contract address`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { let errorThrown = false; - try { - await I_ModuleRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert Implemenation address should not be 0x`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { let errorThrown = false; - try { - await I_ModuleRegistryProxy.upgradeTo("1.1.0", I_ModuleRegistry.address, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert Implemenation address should not be the same address`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_ModuleRegistry.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { let errorThrown = false; - try { - await I_ModuleRegistryProxy.upgradeTo("1.0.0", I_MockModuleRegistry.address, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert same version as previous is not allowed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.0.0", I_MockModuleRegistry.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { let errorThrown = false; - try { - await I_ModuleRegistryProxy.upgradeTo("", I_MockModuleRegistry.address, {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert empty version string is not allowed`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("", I_MockModuleRegistry.address, {from: account_polymath})); }); it("Should upgrade the version and the implementation address successfully", async() => { @@ -297,26 +256,12 @@ contract ("ModuleRegistryProxy", accounts => { it("Should change the ownership of the contract -- because of bad owner", async()=> { let errorThrown = false; - try { - await I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp}); - } catch(error) { - console.log(` tx -> revert because of bad owner`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); }); it("Should change the ownership of the contract -- new address should not be 0x", async()=> { let errorThrown = false; - try { - await I_ModuleRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath}); - } catch(error) { - console.log(` tx -> revert because new owner address should not be 0x`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); }); it("Should change the ownership of the contract", async()=> { diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 4aa6c2e1e..0f088c0be 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -2,6 +2,7 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; +import { catchRevert } from './helpers/exceptions'; const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -323,14 +324,7 @@ contract('TrackedRedemption', accounts => { await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); let errorThrown = false; - try { - let tx = await I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1}); - } catch(error) { - console.log(` tx -> failed insufficent allowance`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1})); }); it("Redeem some tokens", async() => { From e0e932c239241461529ccade17d58136dfe20744 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 4 Oct 2018 22:13:45 +0530 Subject: [PATCH 053/142] Removed try{ (no space) as well --- test/a_poly_oracle.js | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/test/a_poly_oracle.js b/test/a_poly_oracle.js index 23ca4f6e0..ea61966df 100644 --- a/test/a_poly_oracle.js +++ b/test/a_poly_oracle.js @@ -169,13 +169,7 @@ let requestIds = new Array(); it("Should change the gas price manually - fails - bad owner", async() => { let errorThrown = false; - try{ - await I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : accounts[6]}); - } catch(error){ - errorThrown = true; - console.log(` tx->revert msg.sender is not the owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : accounts[6]})); }); it("Should change the gas price manually", async() => { @@ -203,13 +197,7 @@ let requestIds = new Array(); it("Should change the gas limit manually - fails", async() => { let errorThrown = false; - try{ - await I_PolyOracle.setGasLimit(50000,{from : accounts[6]}); - } catch(error){ - errorThrown = true; - console.log(` tx->revert msg.sender is not owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.setGasLimit(50000,{from : accounts[6]})); }); it("Should change the gas limit manually", async() => { @@ -222,12 +210,7 @@ let requestIds = new Array(); it("Should blacklist some IDS manually - fails - wrong size", async() => { let errorThrown = false; let ignore = [true]; - try{ - await I_PolyOracle.setIgnoreRequestIds(requestIds,ignore,{from : accounts[6]}); - } catch(error){ - errorThrown = true; - console.log(` tx->revert msg.sender is not owner`.grey); - } + await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds,ignore,{from : accounts[6]})); }); it("Should blacklist some IDS manually", async() => { @@ -245,13 +228,7 @@ let requestIds = new Array(); it("Should change the oraclize time tolerance manually - fails", async() => { let errorThrown = false; - try{ - await I_PolyOracle.setOraclizeTimeTolerance(3600,{from : accounts[6]}); - } catch(error){ - errorThrown = true; - console.log(` tx->revert msg.sender is not the owner`.grey); - } - assert.ok(errorThrown, message); + await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600,{from : accounts[6]})); }) it("Should change the oraclize time tolerance manually", async() => { From 3b1eb69bef2888075cf59c5cd5a155948d4450fb Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Thu, 4 Oct 2018 14:44:43 -0300 Subject: [PATCH 054/142] re-ordered functions --- .../GeneralPermissionManager.sol | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 494b5a2d9..40a85cf30 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -88,15 +88,31 @@ contract GeneralPermissionManager is IPermissionManager, Module { emit ChangePermission(_delegate, _module, _perm, _valid, now); return true; } - + /** - * @notice Use to get the Permission flag related the `this` contract - * @return Array of permission flags + * @notice Use to change one or more permissions for a single delegate at once + * @param _delegate Ethereum address of the delegate + * @param _multiModules Multiple module matching the multiperms, needs to be same length + * @param _multiPerms Multiple permission flag needs to be changed + * @return nothing */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); - allPermissions[0] = CHANGE_PERMISSION; - return allPermissions; + function changePermissionMulti( + address _delegate, + address[] _multiModules, + bytes32[] _multiPerms + ) + external + withPerm(CHANGE_PERMISSION) + { + require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); + require(_multiModules.length != 0 && _multiPerms.length !=0); + require(_multiModules.length == _multiPerms.length, "modules and permission length are not same"); + + for(uint8 i=0;i<_multiPerms.length;i++){ + bool _currentPerm = !perms[_multiModules[i]][_delegate][_multiPerms[i]]; + perms[_multiModules[i]][_delegate][_multiPerms[i]] = _currentPerm; + emit ChangePermission(_delegate, _multiModules[i], _multiPerms[i], _currentPerm, now); + } } /** @@ -123,40 +139,12 @@ contract GeneralPermissionManager is IPermissionManager, Module { } } - /** - * @notice Use to change one or more permissions for a single delegate at once - * @param _delegate Ethereum address of the delegate - * @param _multiModules Multiple module matching the multiperms, needs to be same length - * @param _multiPerms Multiple permission flag needs to be changed - * @return nothing - */ - function changePermissionMulti( - address _delegate, - address[] _multiModules, - bytes32[] _multiPerms - ) - external - withPerm(CHANGE_PERMISSION) - { - require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); - require(_multiModules.length != 0 && _multiPerms.length !=0); - require(_multiModules.length == _multiPerms.length, "modules and permission length are not same"); - - for(uint8 i=0;i<_multiPerms.length;i++){ - bool _currentPerm = !perms[_multiModules[i]][_delegate][_multiPerms[i]]; - perms[_multiModules[i]][_delegate][_multiPerms[i]] = _currentPerm; - emit ChangePermission(_delegate, _multiModules[i], _multiPerms[i], _currentPerm, now); - } - } - /** * @notice use to return all delegates with a given permission and module * @param _module Ethereum contract address of the module * @param _perm Permission flag * @return address[] */ - - function getAllDelegatesWithPerm(address _module, bytes32 _perm) public view returns(address[]) { require(_module != address(0) && _perm != bytes32(0)); @@ -189,7 +177,6 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @return address[] the address array of Modules this delegate has permission * @return bytes32[] the permission array of the corresponding Modules */ - function getAllModulesAndPermsFromTypes(address _delegate, uint8[] _types, address _tokenAddress) public view returns(address[], bytes32[]) { require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); @@ -236,5 +223,15 @@ contract GeneralPermissionManager is IPermissionManager, Module { return(_allModules, _allPerms); } + + /** + * @notice Returns the Permission flag related the `this` contract + * @return Array of permission flags + */ + function getPermissions() public view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](1); + allPermissions[0] = CHANGE_PERMISSION; + return allPermissions; + } } From 662917008aa6e4035e0a19badd3a5aaecf9354f9 Mon Sep 17 00:00:00 2001 From: satyam Date: Thu, 4 Oct 2018 23:21:07 +0530 Subject: [PATCH 055/142] app proper spacing and imrovements --- .../GeneralPermissionManager.sol | 234 ++++++++---------- .../PermissionManager/IPermissionManager.sol | 80 +++++- 2 files changed, 182 insertions(+), 132 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 494b5a2d9..15bf8dd62 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -20,7 +20,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { bytes32 public constant CHANGE_PERMISSION = "CHANGE_PERMISSION"; /// Event emitted after any permission get changed for the delegate - event ChangePermission(address _delegate, address _module, bytes32 _perm, bool _valid, uint256 _timestamp); + event ChangePermission(address indexed _delegate, address _module, bytes32 _perm, bool _valid, uint256 _timestamp); /// Use to notify when delegate is added in permission manager contract event AddDelegate(address indexed _delegate, bytes32 _details, uint256 _timestamp); @@ -32,181 +32,145 @@ contract GeneralPermissionManager is IPermissionManager, Module { } /** - * @notice Init function i.e generalise function to maintain the structure of the module contract - * @return bytes4 - */ + * @notice Init function i.e generalise function to maintain the structure of the module contract + * @return bytes4 + */ function getInitFunction() public pure returns (bytes4) { return bytes4(0); } /** - * @notice Use to check the permission on delegate corresponds to module contract address - * @param _delegate Ethereum address of the delegate - * @param _module Ethereum contract address of the module - * @param _perm Permission flag - * @return bool - */ + * @notice Use to check the permission on delegate corresponds to module contract address + * @param _delegate Ethereum address of the delegate + * @param _module Ethereum contract address of the module + * @param _perm Permission flag + * @return bool + */ function checkPermission(address _delegate, address _module, bytes32 _perm) external view returns(bool) { if (delegateDetails[_delegate] != bytes32(0)) { return perms[_module][_delegate][_perm]; - }else + } else return false; } /** - * @notice Use to add a delegate - * @param _delegate Ethereum address of the delegate - * @param _details Details about the delegate i.e `Belongs to financial firm` - */ - function addDelegate(address _delegate, bytes32 _details) public withPerm(CHANGE_PERMISSION) { - require(_details != bytes32(0), "Delegate details not set"); + * @notice Use to add a delegate + * @param _delegate Ethereum address of the delegate + * @param _details Details about the delegate i.e `Belongs to financial firm` + */ + function addDelegate(address _delegate, bytes32 _details) external withPerm(CHANGE_PERMISSION) { + require(_details != bytes32(0), "0 value not allowed"); delegateDetails[_delegate] = _details; allDelegates.push(_delegate); emit AddDelegate(_delegate, _details, now); } /** - * @notice Use to provide/change the permission to the delegate corresponds to the module contract - * @param _delegate Ethereum address of the delegate - * @param _module Ethereum contract address of the module - * @param _perm Permission flag - * @param _valid Bool flag use to switch on/off the permission - * @return bool - */ + * @notice use to check if an address is a delegate or not + * @param _potentialDelegate the address of potential delegate + * @return bool + */ + function checkDelegate(address _potentialDelegate) external view returns(bool) { + require(_potentialDelegate != address(0)); + + if (delegateDetails[_potentialDelegate] != bytes32(0)) { + return true; + } else + return false; + } + + /** + * @notice Use to provide/change the permission to the delegate corresponds to the module contract + * @param _delegate Ethereum address of the delegate + * @param _module Ethereum contract address of the module + * @param _perm Permission flag + * @param _valid Bool flag use to switch on/off the permission + * @return bool + */ function changePermission( address _delegate, address _module, bytes32 _perm, bool _valid ) - external + public withPerm(CHANGE_PERMISSION) - returns(bool) { - require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); + require(delegateDetails[_delegate] != bytes32(0), "Delegate is not exists"); perms[_module][_delegate][_perm] = _valid; emit ChangePermission(_delegate, _module, _perm, _valid, now); - return true; - } - - /** - * @notice Use to get the Permission flag related the `this` contract - * @return Array of permission flags - */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); - allPermissions[0] = CHANGE_PERMISSION; - return allPermissions; - } - - /** - * @notice use to get all delegates - * @return address[] - */ - function getAllDelegates() public view returns(address[]) { - return allDelegates; - } - - /** - * @notice use to check if an address is a delegate or not - * @param _potentialDelegate the address of potential delegate - * @return bool - */ - function checkDelegate(address _potentialDelegate) public view returns(bool) { - - require(_potentialDelegate != address(0)); - - if (delegateDetails[_potentialDelegate] != bytes32(0)) { - return true; - }else{ - return false; - } } /** - * @notice Use to change one or more permissions for a single delegate at once - * @param _delegate Ethereum address of the delegate - * @param _multiModules Multiple module matching the multiperms, needs to be same length - * @param _multiPerms Multiple permission flag needs to be changed - * @return nothing - */ + * @notice Use to change one or more permissions for a single delegate at once + * @param _delegate Ethereum address of the delegate + * @param _modules Multiple module matching the multiperms, needs to be same length + * @param _perms Multiple permission flag needs to be changed + * @return nothing + */ function changePermissionMulti( address _delegate, - address[] _multiModules, - bytes32[] _multiPerms + address[] _modules, + bytes32[] _perms ) external withPerm(CHANGE_PERMISSION) { - require(delegateDetails[_delegate] != bytes32(0), "Delegate details not set"); - require(_multiModules.length != 0 && _multiPerms.length !=0); - require(_multiModules.length == _multiPerms.length, "modules and permission length are not same"); + require(_modules.length > 0 && _perms.length > 0, "0 length is not allowed"); + require(_modules.length == _perms.length, "Array length mismatch"); - for(uint8 i=0;i<_multiPerms.length;i++){ - bool _currentPerm = !perms[_multiModules[i]][_delegate][_multiPerms[i]]; - perms[_multiModules[i]][_delegate][_multiPerms[i]] = _currentPerm; - emit ChangePermission(_delegate, _multiModules[i], _multiPerms[i], _currentPerm, now); + for(uint8 i = 0; i < _perms.length; i++) { + bool _perm = !perms[_modules[i]][_delegate][_perms[i]]; + changePermission(_delegate, _modules[i], _perms[i], _perm); } } /** - * @notice use to return all delegates with a given permission and module - * @param _module Ethereum contract address of the module - * @param _perm Permission flag - * @return address[] - */ - - - function getAllDelegatesWithPerm(address _module, bytes32 _perm) public view returns(address[]) { - - require(_module != address(0) && _perm != bytes32(0)); - + * @notice use to return all delegates with a given permission and module + * @param _module Ethereum contract address of the module + * @param _perm Permission flag + * @return address[] + */ + function getAllDelegatesWithPerm(address _module, bytes32 _perm) external view returns(address[]) { + require(_module != address(0) && _perm != bytes32(0), "0 values not allowed"); uint256 counter = 0; - - for(uint8 j=0;jgetModulesByType - for(uint8 i=0; i<_types.length; i++){ + for (uint8 i = 0; i < _types.length; i++) { address[] memory _currentTypeModules = ISecurityToken(_tokenAddress).getModulesByType(_types[i]); - - // loop through each modules to get their perms from iModule->getPermissions - for(uint8 a=0; a<_currentTypeModules.length; a++){ - bytes32[] memory _allModulePerms = IModule(_currentTypeModules[a]).getPermissions(); - + // loop through each modules to get their perms from IModule->getPermissions + for (uint8 j = 0; j < _currentTypeModules.length; j++){ + bytes32[] memory _allModulePerms = IModule(_currentTypeModules[j]).getPermissions(); // loop through each perm, if it is true, push results into arrays - for (uint8 b=0; b<_allModulePerms.length; b++){ - if(perms[_currentTypeModules[a]][_delegate][_allModulePerms[b]]){ + for (uint8 k = 0; k < _allModulePerms.length; k++) { + if (perms[_currentTypeModules[j]][_delegate][_allModulePerms[k]]) { counter ++; } } @@ -215,19 +179,16 @@ contract GeneralPermissionManager is IPermissionManager, Module { address[] memory _allModules = new address[](counter); bytes32[] memory _allPerms = new bytes32[](counter); + counter = 0; - counter=0; - - for( i=0; i<_types.length; i++){ + for (i = 0; i < _types.length; i++){ _currentTypeModules = ISecurityToken(_tokenAddress).getModulesByType(_types[i]); - - for(a=0; a<_currentTypeModules.length; a++){ - _allModulePerms = IModule(_currentTypeModules[a]).getPermissions(); - - for (b=0; b<_allModulePerms.length; b++){ - if(perms[_currentTypeModules[a]][_delegate][_allModulePerms[b]]){ - _allModules[counter]= _currentTypeModules[a]; - _allPerms[counter]=_allModulePerms[b]; + for (j = 0; j < _currentTypeModules.length; j++) { + _allModulePerms = IModule(_currentTypeModules[j]).getPermissions(); + for (k = 0; k < _allModulePerms.length; k++) { + if (perms[_currentTypeModules[j]][_delegate][_allModulePerms[k]]) { + _allModules[counter]= _currentTypeModules[j]; + _allPerms[counter]=_allModulePerms[k]; counter++; } } @@ -237,4 +198,23 @@ contract GeneralPermissionManager is IPermissionManager, Module { return(_allModules, _allPerms); } + /** + * @notice Use to get the Permission flag related the `this` contract + * @return Array of permission flags + */ + function getPermissions() external view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](1); + allPermissions[0] = CHANGE_PERMISSION; + return allPermissions; + } + + /** + * @notice use to get all delegates + * @return address[] + */ + function getAllDelegates() external view returns(address[]) { + return allDelegates; + } + + } diff --git a/contracts/modules/PermissionManager/IPermissionManager.sol b/contracts/modules/PermissionManager/IPermissionManager.sol index 3039b97c0..83493d0af 100644 --- a/contracts/modules/PermissionManager/IPermissionManager.sol +++ b/contracts/modules/PermissionManager/IPermissionManager.sol @@ -5,18 +5,88 @@ pragma solidity ^0.4.24; */ interface IPermissionManager { + /** + * @notice Use to check the permission on delegate corresponds to module contract address + * @param _delegate Ethereum address of the delegate + * @param _module Ethereum contract address of the module + * @param _perm Permission flag + * @return bool + */ function checkPermission(address _delegate, address _module, bytes32 _perm) external view returns(bool); - function getPermissions() external view returns(bytes32[]); - - function getAllDelegates() external view returns(address[]); + /** + * @notice Use to add a delegate + * @param _delegate Ethereum address of the delegate + * @param _details Details about the delegate i.e `Belongs to financial firm` + */ + function addDelegate(address _delegate, bytes32 _details) external; + /** + * @notice use to check if an address is a delegate or not + * @param _potentialDelegate the address of potential delegate + * @return bool + */ function checkDelegate(address _potentialDelegate) external view returns(bool); + /** + * @notice Use to provide/change the permission to the delegate corresponds to the module contract + * @param _delegate Ethereum address of the delegate + * @param _module Ethereum contract address of the module + * @param _perm Permission flag + * @param _valid Bool flag use to switch on/off the permission + * @return bool + */ + function changePermission( + address _delegate, + address _module, + bytes32 _perm, + bool _valid + ) + external; + + /** + * @notice Use to change one or more permissions for a single delegate at once + * @param _delegate Ethereum address of the delegate + * @param _modules Multiple module matching the multiperms, needs to be same length + * @param _perms Multiple permission flag needs to be changed + * @return nothing + */ + function changePermissionMulti( + address _delegate, + address[] _modules, + bytes32[] _perms + ) + external; + + /** + * @notice use to return all delegates with a given permission and module + * @param _module Ethereum contract address of the module + * @param _perm Permission flag + * @return address[] + */ function getAllDelegatesWithPerm(address _module, bytes32 _perm) external view returns(address[]); - function getAllModulesAndPermsFromTypes(address _delegate, uint8[] _types, address _tokenAddress) public view returns(address[], bytes32[]); + /** + * @notice use to return all permission of a single or multiple module + * @dev possible that function get out of gas is there are lot of modules and perm related to them + * @param _delegate Ethereum address of the delegate + * @param _tokenAddress Ethereum address of the security token + * @param _types uint8[] of types + * @return address[] the address array of Modules this delegate has permission + * @return bytes32[] the permission array of the corresponding Modules + */ + function getAllModulesAndPermsFromTypes(address _delegate, uint8[] _types, address _tokenAddress) external view returns(address[], bytes32[]); + + /** + * @notice Use to get the Permission flag related the `this` contract + * @return Array of permission flags + */ + function getPermissions() external view returns(bytes32[]); - function changePermission(address _delegate, address _module, bytes32 _perm, bool _valid) external returns(bool); + /** + * @notice use to get all delegates + * @return address[] + */ + function getAllDelegates() external view returns(address[]); } From de69a714a5ec97b68b88c89c1ec444d0e00c35c2 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Thu, 4 Oct 2018 19:10:20 +0100 Subject: [PATCH 056/142] Add additional transfer / mint / burn functions with _data parameter --- contracts/interfaces/ISecurityToken.sol | 84 ++++++++++++----- contracts/modules/Burn/TrackedRedemption.sol | 2 +- .../TransferManager/CountTransferManager.sol | 2 +- .../GeneralTransferManager.sol | 2 +- .../TransferManager/ITransferManager.sol | 2 +- .../ManualApprovalTransferManager.sol | 2 +- .../PercentageTransferManager.sol | 2 +- contracts/tokens/SecurityToken.sol | 89 ++++++++++++++----- test/c_checkpoints.js | 2 +- test/j_manual_approval_transfer_manager.js | 10 +-- test/o_security_token.js | 16 ++-- 11 files changed, 145 insertions(+), 68 deletions(-) diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index b0cbd22b1..20dcb72c8 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -30,17 +30,28 @@ interface ISecurityToken { function mint(address _investor, uint256 _value) external returns (bool success); /** - * @notice Burn function used to burn the securityToken - * @param _value No. of tokens that get burned + * @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) + * @param _investor address the tokens will be minted to + * @param _value is the amount of tokens that will be minted to the investor + * @param _data data to indicate validation */ - function burn(uint256 _value) external; + function mintWithData(address _investor, uint256 _value, bytes _data) external returns (bool success); /** * @notice Burn function used to burn the securityToken on behalf of someone else * @param _from Address for whom to burn tokens * @param _value No. of token that get burned + * @param _data data to indicate validation */ - function burnFrom(address _from, uint256 _value) external; + function burnFromWithData(address _from, uint256 _value, bytes _data) external; + + /** + * @notice Burn function used to burn the securityToken + * @param _value No. of tokens that get burned + * @param _data data to indicate validation + */ + function burnWithData(uint256 _value, bytes _data) external; event Minted(address indexed _to, uint256 _value); event Burnt(address indexed _burner, uint256 _value); @@ -175,10 +186,22 @@ interface ISecurityToken { function mintMulti(address[] _investors, uint256[] _values) external returns (bool success); /** - * @notice Removes a module attached to the SecurityToken - * @param _module address of module to archive - */ - function removeModule(address _module) external; + * @notice Function used to attach a module to the security token + * @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it + * @dev to control restrictions on transfers. + * @dev You are allowed to add a new moduleType if: + * @dev - there is no existing module of that type yet added + * @dev - the last member of the module list is replacable + * @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 module. (WIP) + */ + function addModule( + address _moduleFactory, + bytes _data, + uint256 _maxCost, + uint256 _budget + ) external; /** * @notice Archives a module attached to the SecurityToken @@ -193,18 +216,10 @@ interface ISecurityToken { function unarchiveModule(address _module) external; /** - * @notice Function used to attach the module in security token - * @param _moduleFactory Contract address of the module factory that needs to be attached - * @param _data Data used for the intialization of the module factory variables - * @param _maxCost Maximum cost of the Module factory - * @param _budget Budget of the Module factory - */ - function addModule( - address _moduleFactory, - bytes _data, - uint256 _maxCost, - uint256 _budget - ) external; + * @notice Removes a module attached to the SecurityToken + * @param _module address of module to archive + */ + function removeModule(address _module) external; /** * @notice Use by the issuer to set the controller addresses @@ -217,17 +232,19 @@ interface ISecurityToken { * @param _from address from which to take tokens * @param _to address where to send tokens * @param _value amount of tokens to transfer - * @param _data data attached to the transfer by controller to emit in event + * @param _data data to indicate validation + * @param _log data attached to the transfer by controller to emit in event */ - function forceTransfer(address _from, address _to, uint256 _value, bytes _data) external; + function forceTransfer(address _from, address _to, uint256 _value, bytes _data, bytes _log) external; /** * @notice Use by a controller to execute a foced burn * @param _from address from which to take tokens * @param _value amount of tokens to transfer - * @param _data data attached to the transfer by controller to emit in event + * @param _data data to indicate validation + * @param _log data attached to the transfer by controller to emit in event */ - function forceBurn(address _from, uint256 _value, bytes _data) external; + function forceBurn(address _from, uint256 _value, bytes _data, bytes _log) external; /** * @notice Use by the issuer to permanently disable controller functionality @@ -244,4 +261,23 @@ interface ISecurityToken { * @notice gets the investor count */ function getInvestorCount() external view returns(uint256); + + /** + * @notice Overloaded version of the transfer function + * @param _to receiver of transfer + * @param _value value of transfer + * @param _data data to indicate validation + * @return bool success + */ + function transferWithData(address _to, uint256 _value, bytes _data) external returns (bool success); + + /** + * @notice Overloaded version of the transferFrom function + * @param _from sender of transfer + * @param _to receiver of transfer + * @param _value value of transfer + * @param _data data to indicate validation + * @return bool success + */ + function transferFromWithData(address _from, address _to, uint256 _value, bytes _data) external returns(bool); } diff --git a/contracts/modules/Burn/TrackedRedemption.sol b/contracts/modules/Burn/TrackedRedemption.sol index 44a0b1d0e..f6211a140 100644 --- a/contracts/modules/Burn/TrackedRedemption.sol +++ b/contracts/modules/Burn/TrackedRedemption.sol @@ -37,7 +37,7 @@ contract TrackedRedemption is IBurn, Module { * @param _value The number of tokens to redeem */ function redeemTokens(uint256 _value) public { - ISecurityToken(securityToken).burnFrom(msg.sender, _value); + ISecurityToken(securityToken).burnFromWithData(msg.sender, _value, ""); redeemedTokens[msg.sender] = redeemedTokens[msg.sender].add(_value); emit Redeemed(msg.sender, _value, now); } diff --git a/contracts/modules/TransferManager/CountTransferManager.sol b/contracts/modules/TransferManager/CountTransferManager.sol index 565a03033..32df49dd4 100644 --- a/contracts/modules/TransferManager/CountTransferManager.sol +++ b/contracts/modules/TransferManager/CountTransferManager.sol @@ -26,7 +26,7 @@ contract CountTransferManager is ITransferManager { } /// @notice Used to verify the transfer transaction according to the rule implemented in the trnasfer managers - function verifyTransfer(address /* _from */, address _to, uint256 /* _amount */, bool /* _isTransfer */) public returns(Result) { + function verifyTransfer(address /* _from */, address _to, uint256 /* _amount */, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { if (!paused) { if (maxHolderCount < ISecurityToken(securityToken).getInvestorCount()) { // Allow transfers to existing maxHolders diff --git a/contracts/modules/TransferManager/GeneralTransferManager.sol b/contracts/modules/TransferManager/GeneralTransferManager.sol index 3cd7e9152..707927b93 100644 --- a/contracts/modules/TransferManager/GeneralTransferManager.sol +++ b/contracts/modules/TransferManager/GeneralTransferManager.sol @@ -151,7 +151,7 @@ contract GeneralTransferManager is ITransferManager { * b) Seller's sale lockup period is over * c) Buyer's purchase lockup is over */ - function verifyTransfer(address _from, address _to, uint256 /*_amount*/, bool /* _isTransfer */) public returns(Result) { + function verifyTransfer(address _from, address _to, uint256 /*_amount*/, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { if (!paused) { if (allowAllTransfers) { //All transfers allowed, regardless of whitelist diff --git a/contracts/modules/TransferManager/ITransferManager.sol b/contracts/modules/TransferManager/ITransferManager.sol index 8279e68c5..3f736801c 100644 --- a/contracts/modules/TransferManager/ITransferManager.sol +++ b/contracts/modules/TransferManager/ITransferManager.sol @@ -16,7 +16,7 @@ contract ITransferManager is Module, Pausable { // NA, then the result from this TM is ignored enum Result {INVALID, NA, VALID, FORCE_VALID} - function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result); + function verifyTransfer(address _from, address _to, uint256 _amount, bytes _data, bool _isTransfer) public returns(Result); function unpause() onlyOwner public { super._unpause(); diff --git a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol index 04629995a..e4f5d35f0 100644 --- a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol +++ b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol @@ -87,7 +87,7 @@ contract ManualApprovalTransferManager is ITransferManager { * b) Seller's sale lockup period is over * c) Buyer's purchase lockup is over */ - function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { + function verifyTransfer(address _from, address _to, uint256 _amount, bytes /* _data */, bool _isTransfer) public returns(Result) { // function must only be called by the associated security token if _isTransfer == true require(_isTransfer == false || msg.sender == securityToken, "Sender is not owner"); // manual blocking takes precidence over manual approval diff --git a/contracts/modules/TransferManager/PercentageTransferManager.sol b/contracts/modules/TransferManager/PercentageTransferManager.sol index 805d04557..0e67539af 100644 --- a/contracts/modules/TransferManager/PercentageTransferManager.sol +++ b/contracts/modules/TransferManager/PercentageTransferManager.sol @@ -38,7 +38,7 @@ contract PercentageTransferManager is ITransferManager { } /// @notice Used to verify the transfer transaction according to the rule implemented in the trnasfer managers - function verifyTransfer(address /* _from */, address _to, uint256 _amount, bool /* _isTransfer */) public returns(Result) { + function verifyTransfer(address /* _from */, address _to, uint256 _amount, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { if (!paused) { // If an address is on the whitelist, it is allowed to hold more than maxHolderPercentage of the tokens. if (whitelist[_to]) { diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 83724284e..2b021c372 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -464,7 +464,18 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return bool success */ function transfer(address _to, uint256 _value) public returns (bool success) { - require(_updateTransfer(msg.sender, _to, _value), "Transfer not valid"); + return transferWithData(_to, _value, ""); + } + + /** + * @notice Overloaded version of the transfer function + * @param _to receiver of transfer + * @param _value value of transfer + * @param _data data to indicate validation + * @return bool success + */ + function transferWithData(address _to, uint256 _value, bytes _data) public returns (bool success) { + require(_updateTransfer(msg.sender, _to, _value, _data), "Transfer not valid"); require(super.transfer(_to, _value)); return true; } @@ -477,16 +488,28 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return bool success */ function transferFrom(address _from, address _to, uint256 _value) public returns(bool) { - require(_updateTransfer(_from, _to, _value), "Transfer not valid"); + return transferFromWithData(_from, _to, _value, ""); + } + + /** + * @notice Overloaded version of the transferFrom function + * @param _from sender of transfer + * @param _to receiver of transfer + * @param _value value of transfer + * @param _data data to indicate validation + * @return bool success + */ + function transferFromWithData(address _from, address _to, uint256 _value, bytes _data) public returns(bool) { + require(_updateTransfer(_from, _to, _value, _data), "Transfer not valid"); require(super.transferFrom(_from, _to, _value)); return true; } - function _updateTransfer(address _from, address _to, uint256 _value) internal returns(bool) { + function _updateTransfer(address _from, address _to, uint256 _value, bytes _data) internal returns(bool) { _adjustInvestorCount(_from, _to, _value); _adjustBalanceCheckpoints(_from); _adjustBalanceCheckpoints(_to); - return _verifyTransfer(_from, _to, _value, true); + return _verifyTransfer(_from, _to, _value, _data, true); } /** @@ -495,10 +518,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _from sender of transfer * @param _to receiver of transfer * @param _value value of transfer + * @param _data data to indicate validation * @param _isTransfer whether transfer is being executed * @return bool */ - function _verifyTransfer(address _from, address _to, uint256 _value, bool _isTransfer) internal checkGranularity(_value) returns (bool) { + function _verifyTransfer(address _from, address _to, uint256 _value, bytes _data, bool _isTransfer) internal checkGranularity(_value) returns (bool) { if (!transfersFrozen) { if (modules[TRANSFER_KEY].length == 0) { return true; @@ -512,7 +536,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr module = modules[TRANSFER_KEY][i]; if (!modulesToData[module].isArchived) { unarchived = true; - ITransferManager.Result valid = ITransferManager(module).verifyTransfer(_from, _to, _value, _isTransfer); + ITransferManager.Result valid = ITransferManager(module).verifyTransfer(_from, _to, _value, _data, _isTransfer); if (valid == ITransferManager.Result.INVALID) { isInvalid = true; } @@ -536,10 +560,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _from sender of transfer * @param _to receiver of transfer * @param _value value of transfer + * @param _data data to indicate validation * @return bool */ - function verifyTransfer(address _from, address _to, uint256 _value) public returns (bool) { - return _verifyTransfer(_from, _to, _value, false); + function verifyTransfer(address _from, address _to, uint256 _value, bytes _data) public returns (bool) { + return _verifyTransfer(_from, _to, _value, _data, false); } /** @@ -558,9 +583,21 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _value Number of tokens be minted * @return success */ - function mint(address _investor, uint256 _value) public onlyModuleOrOwner(MINT_KEY) checkGranularity(_value) isMintingAllowed() returns (bool success) { + function mint(address _investor, uint256 _value) public returns (bool success) { + return mintWithData(_investor, _value, ""); + } + + /** + * @notice mints new tokens and assigns them to the target _investor. + * @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 _value Number of tokens be minted + * @param _data data to indicate validation + * @return success + */ + function mintWithData(address _investor, uint256 _value, bytes _data) public onlyModuleOrOwner(MINT_KEY) isMintingAllowed() returns (bool success) { require(_investor != address(0), "Investor is 0"); - require(_updateTransfer(address(0), _investor, _value), "Transfer not valid"); + require(_updateTransfer(address(0), _investor, _value, _data), "Transfer not valid"); _adjustTotalSupplyCheckpoints(); totalSupply_ = totalSupply_.add(_value); balances[_investor] = balances[_investor].add(_value); @@ -597,9 +634,9 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return TokenLib.checkPermission(modules[PERMISSION_KEY], _delegate, _module, _perm); } - function _burn(address _from, uint256 _value) internal returns(bool) { + function _burn(address _from, uint256 _value, bytes _data) internal returns(bool) { require(_value <= balances[_from], "Value too high"); - bool verified = _updateTransfer(_from, address(0), _value); + bool verified = _updateTransfer(_from, address(0), _value, _data); _adjustTotalSupplyCheckpoints(); balances[_from] = balances[_from].sub(_value); totalSupply_ = totalSupply_.sub(_value); @@ -611,20 +648,22 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr /** * @notice Burn function used to burn the securityToken * @param _value No. of tokens that get burned + * @param _data data to indicate validation */ - function burn(uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public { - require(_burn(msg.sender, _value), "Burn not valid"); + function burnWithData(uint256 _value, bytes _data) onlyModule(BURN_KEY) public { + require(_burn(msg.sender, _value, _data), "Burn not valid"); } /** * @notice Burn function used to burn the securityToken on behalf of someone else * @param _from Address for whom to burn tokens * @param _value No. of tokens that get burned + * @param _data data to indicate validation */ - function burnFrom(address _from, uint256 _value) checkGranularity(_value) onlyModule(BURN_KEY) public { + function burnFromWithData(address _from, uint256 _value, bytes _data) onlyModule(BURN_KEY) public { require(_value <= allowed[_from][msg.sender], "Value too high"); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); - require(_burn(_from, _value), "Burn not valid"); + require(_burn(_from, _value, _data), "Burn not valid"); } /** @@ -693,15 +732,16 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _from address from which to take tokens * @param _to address where to send tokens * @param _value amount of tokens to transfer - * @param _data data attached to the transfer by controller to emit in event + * @param _data data to indicate validation + * @param _log data attached to the transfer by controller to emit in event */ - function forceTransfer(address _from, address _to, uint256 _value, bytes _data) public onlyController { + function forceTransfer(address _from, address _to, uint256 _value, bytes _data, bytes _log) public onlyController { require(_to != address(0)); require(_value <= balances[_from]); - bool verified = _updateTransfer(_from, _to, _value); + bool verified = _updateTransfer(_from, _to, _value, _data); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); - emit ForceTransfer(msg.sender, _from, _to, _value, verified, _data); + emit ForceTransfer(msg.sender, _from, _to, _value, verified, _log); emit Transfer(_from, _to, _value); } @@ -709,11 +749,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice Use by a controller to execute a foced burn * @param _from address from which to take tokens * @param _value amount of tokens to transfer - * @param _data data attached to the transfer by controller to emit in event + * @param _data data to indicate validation + * @param _log data attached to the transfer by controller to emit in event */ - function forceBurn(address _from, uint256 _value, bytes _data) public onlyController { - bool verified = _burn(_from, _value); - emit ForceBurn(msg.sender, _from, _value, verified, _data); + function forceBurn(address _from, uint256 _value, bytes _data, bytes _log) public onlyController { + bool verified = _burn(_from, _value, _data); + emit ForceBurn(msg.sender, _from, _value, verified, _log); } /** diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index d094a2dfc..f4ad15ee1 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -389,7 +389,7 @@ contract('Checkpoints', accounts => { } n = n.toFixed(0); console.log("Burning: " + n.toString() + " from: " + burner); - await I_SecurityToken.forceBurn(burner, n, "", { from: token_owner }); + await I_SecurityToken.forceBurn(burner, n, "", "", { from: token_owner }); } console.log("Checking Interim..."); for (let k = 0; k < cps.length; k++) { diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index cc6471e8a..064027246 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -371,7 +371,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Cannot call verifyTransfer on the TM directly if _isTransfer == true", async() => { let errorThrown = false; try { - await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { from: token_owner }); + await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), "", true, { from: token_owner }); } catch(error) { console.log(` tx revert -> invalid not from SecurityToken`.grey); ensureException(error); @@ -382,7 +382,7 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Can call verifyTransfer on the TM directly if _isTransfer == false", async() => { - await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), false, { from: token_owner }); + await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), "", false, { from: token_owner }); }); it("Add a new token holder", async() => { @@ -503,14 +503,14 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Check verifyTransfer without actually transferring", async() => { - let verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); + let verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether'), ""); console.log(JSON.stringify(verified)); assert.equal(verified, true); - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('2', 'ether')); + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), ""); assert.equal(verified, false); - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether'), ""); assert.equal(verified, true); }); diff --git a/test/o_security_token.js b/test/o_security_token.js index b6abc9b20..de7e2b2ed 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -1157,7 +1157,7 @@ contract('SecurityToken', accounts => { let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); try { - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", { from: account_controller }); + let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", "", { from: account_controller }); } catch(error) { console.log(` tx revert -> value is greater than its current balance`.grey); errorThrown = true; @@ -1171,7 +1171,7 @@ contract('SecurityToken', accounts => { let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); try { - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: token_owner }); + let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", "", { from: token_owner }); } catch(error) { console.log(` tx revert -> not owner`.grey); errorThrown = true; @@ -1184,7 +1184,7 @@ contract('SecurityToken', accounts => { let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); // console.log(currentInvestorCount.toString(), currentBalance.toString()); - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: account_controller }); + let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", "", { from: account_controller }); // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); let newInvestorCount = await I_SecurityToken.getInvestorCount.call(); @@ -1261,7 +1261,7 @@ contract('SecurityToken', accounts => { it("Should fail to forceTransfer because not approved controller", async() => { let errorThrown1 = false; try { - await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_investor1}); + await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", {from: account_investor1}); } catch (error) { console.log(` tx revert -> not approved controller`.grey); errorThrown1 = true; @@ -1273,7 +1273,7 @@ contract('SecurityToken', accounts => { it("Should fail to forceTransfer because insufficient balance", async() => { let errorThrown = false; try { - await I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); + await I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller}); } catch (error) { console.log(` tx revert -> insufficient balance`.grey); errorThrown = true; @@ -1285,7 +1285,7 @@ contract('SecurityToken', accounts => { it("Should fail to forceTransfer because recipient is zero address", async() => { let errorThrown = false; try { - await I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); + await I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller}); } catch (error) { console.log(` tx revert -> recipient is zero address`.grey); errorThrown = true; @@ -1302,7 +1302,7 @@ contract('SecurityToken', accounts => { let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); - let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); + let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller}); let end_investorCount = await I_SecurityToken.getInvestorCount.call(); let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); @@ -1391,7 +1391,7 @@ contract('SecurityToken', accounts => { it("Should fail to forceTransfer because controller functionality frozen", async() => { let errorThrown = false; try { - await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); + await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller}); } catch (error) { console.log(` tx revert -> recipient is zero address`.grey); errorThrown = true; From 1e28f636862714e4631f40287a0cafd5ea4805bb Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 08:42:13 +0530 Subject: [PATCH 057/142] cleanup --- ex.js | 15 +--- test/a_poly_oracle.js | 22 ++--- test/b_capped_sto.js | 46 +++++----- test/d_count_transfer_manager.js | 8 +- test/f_ether_dividends.js | 44 +++++----- test/g_general_permission_manager.js | 8 +- test/h_general_transfer_manager.js | 32 +++---- test/j_manual_approval_transfer_manager.js | 32 +++---- test/k_module_registry.js | 28 +++---- test/l_percentage_transfer_manager.js | 4 +- test/m_presale_sto.js | 10 +-- test/n_security_token_registry.js | 4 +- test/o_security_token.js | 87 ++++++++++--------- test/p_usd_tiered_sto.js | 98 +++++++++++----------- test/q_usd_tiered_sto_sim.js | 2 +- test/t_security_token_registry_proxy.js | 16 ++-- test/u_module_registry_proxy.js | 16 ++-- test/v_tracked_redemptions.js | 2 +- 18 files changed, 232 insertions(+), 242 deletions(-) diff --git a/ex.js b/ex.js index 97a5fb222..570a48ee2 100644 --- a/ex.js +++ b/ex.js @@ -1,9 +1,9 @@ var fs = require('fs') const regex = /(?<=try {)(.*?)(await )(.*?)(?=;)(.*?)(?=message\);)/gmis; const regex2 = /(try {)(.*?)(message\);)/gmis; -let m; - +const regex3 = /(let errorThrown. = false;)/gmis; const dirname = 'test/'; + fs.readdir(dirname, function(err, filenames) { if (err) { return console.log(err); @@ -15,17 +15,10 @@ fs.readdir(dirname, function(err, filenames) { } content = content.replace(regex, 'catchRevert($3);'); content = content.replace(regex2, 'await $2'); + content = content.replace(regex3, ''); fs.writeFile(dirname + filename, content, 'utf8', function (err) { if (err) return console.log(err); }); }); }); -}); - - - - - - - - +}); \ No newline at end of file diff --git a/test/a_poly_oracle.js b/test/a_poly_oracle.js index ea61966df..da8268238 100644 --- a/test/a_poly_oracle.js +++ b/test/a_poly_oracle.js @@ -55,13 +55,13 @@ let requestIds = new Array(); describe("Scheduling test cases", async() => { it("Should schedule the timing of the call - fails - non owner", async() => { - let errorThrown = false; + let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: accounts[1], value: web3.utils.toWei("2")})); }); it("Should schedule the timing of the call - fails - no value", async() => { - let errorThrown = false; + let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner})); }) @@ -102,7 +102,7 @@ let requestIds = new Array(); }); it("Should schedule to call using iters - fails", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, {from: accounts[6]})); }) @@ -130,7 +130,7 @@ let requestIds = new Array(); describe("Ownable functions", async() => { it("Should change the Poly USD price manually - fail - bad account", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: accounts[5]})); }); @@ -141,7 +141,7 @@ let requestIds = new Array(); }) it("Should freeze the Oracle manually", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.setFreezeOracle(true, {from: accounts[5]})); }) @@ -155,7 +155,7 @@ let requestIds = new Array(); }) it("Should change the sanity bounds manually - fails - bad owner", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : accounts[6]})); }) @@ -168,7 +168,7 @@ let requestIds = new Array(); }); it("Should change the gas price manually - fails - bad owner", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : accounts[6]})); }); @@ -196,7 +196,7 @@ let requestIds = new Array(); }); it("Should change the gas limit manually - fails", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.setGasLimit(50000,{from : accounts[6]})); }); @@ -208,7 +208,7 @@ let requestIds = new Array(); }); it("Should blacklist some IDS manually - fails - wrong size", async() => { - let errorThrown = false; + let ignore = [true]; await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds,ignore,{from : accounts[6]})); }); @@ -227,7 +227,7 @@ let requestIds = new Array(); }); it("Should change the oraclize time tolerance manually - fails", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600,{from : accounts[6]})); }) @@ -238,7 +238,7 @@ let requestIds = new Array(); }); it("should change the api URL manually", async() => { - let errorThrown = false; + await catchRevert(I_PolyOracle.setOracleURL(alternateURL, {from: accounts[6]})); }) diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index ba431e1db..6bc815bdc 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -201,7 +201,7 @@ contract('CappedSTO', accounts => { }); it("Should mint the tokens before attaching the STO", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), {from: token_owner})); }); @@ -211,7 +211,7 @@ contract('CappedSTO', accounts => { await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - let errorThrown = false; + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); @@ -221,13 +221,13 @@ contract('CappedSTO', accounts => { await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner}); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - let errorThrown = false; + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to launch the STO due to startTime > endTime", async () => { let bytesSTO = encodeModuleCall(STOParameters, [ Math.floor(Date.now()/1000 + 100000), Math.floor(Date.now()/1000 + 1000), cap, rate, [E_fundRaiseType], account_fundsReceiver]); - let errorThrown = false; + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); @@ -235,7 +235,7 @@ contract('CappedSTO', accounts => { let startTime = latestTime() + duration.days(1); let endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [ startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); - let errorThrown = false; + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); @@ -285,7 +285,7 @@ contract('CappedSTO', accounts => { describe("Buy tokens", async() => { it("Should buy the tokens -- failed due to startTime is greater than Current time", async () => { - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, @@ -294,7 +294,7 @@ contract('CappedSTO', accounts => { }); it("Should buy the tokens -- failed due to invested amount is zero", async () => { - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, @@ -303,7 +303,7 @@ contract('CappedSTO', accounts => { }); it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, @@ -312,7 +312,7 @@ contract('CappedSTO', accounts => { }); it("Should buy the tokens -- Failed due to wrong granularity", async () => { - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, @@ -386,7 +386,7 @@ contract('CappedSTO', accounts => { }); it("Should pause the STO -- Failed due to wrong msg.sender", async()=> { - let errorThrown = false; + await catchRevert(I_CappedSTO_Array_ETH[0].pause({from: account_investor1})); }); @@ -397,7 +397,7 @@ contract('CappedSTO', accounts => { }); it("Should fail to buy the tokens after pausing the STO", async() => { - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, @@ -407,7 +407,7 @@ contract('CappedSTO', accounts => { }); it("Should unpause the STO -- Failed due to wrong msg.sender", async()=> { - let errorThrown = false; + await catchRevert(I_CappedSTO_Array_ETH[0].unpause({from: account_investor1})); }); @@ -417,7 +417,7 @@ contract('CappedSTO', accounts => { }); it("Should buy the tokens -- Failed due to wrong granularity", async () => { - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, @@ -498,7 +498,7 @@ contract('CappedSTO', accounts => { await I_PolyToken.getTokens(value, account_investor1); await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); - let errorThrown = false; + await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); }); @@ -585,7 +585,7 @@ contract('CappedSTO', accounts => { it("Should invest in second STO - fails due to incorrect beneficiary", async() => { // Buying on behalf of another user should fail - let errorThrown = false; + await catchRevert(I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') })); }); @@ -845,13 +845,13 @@ contract('CappedSTO', accounts => { .toNumber(), 45000 ); - let errorThrown = false; + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); }); it("Should failed at the time of buying the tokens -- Because STO get expired", async() => { await increaseTime(duration.days(31)); // increased beyond the end time of the STO - let errorThrown = false; + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); }); @@ -888,12 +888,12 @@ contract('CappedSTO', accounts => { }); it("Should fail to change the title -- bad owner", async() => { - let errorThrown = false; + await catchRevert(I_CappedSTOFactory.changeTitle("STO Capped", {from:account_investor1})); }); it("Should fail to change the title -- zero length", async() => { - let errorThrown = false; + await catchRevert(I_CappedSTOFactory.changeTitle("", {from: token_owner})); }); @@ -905,12 +905,12 @@ contract('CappedSTO', accounts => { }); it("Should fail to change the description -- bad owner", async() => { - let errorThrown = false; + await catchRevert(I_CappedSTOFactory.changeDescription("It is only a STO", {from:account_investor1})); }); it("Should fail to change the description -- zero length", async() => { - let errorThrown = false; + await catchRevert(I_CappedSTOFactory.changeDescription("", {from: token_owner})); }); @@ -922,12 +922,12 @@ contract('CappedSTO', accounts => { }); it("Should fail to change the name -- bad owner", async() => { - let errorThrown = false; + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from:account_investor1})); }); it("Should fail to change the name -- zero length", async() => { - let errorThrown = false; + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(""), {from: token_owner})); }); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index c2c7b631f..a4e7aa565 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -166,7 +166,7 @@ contract('CountTransferManager', accounts => { }); it("Should successfully attach the CountTransferManager factory with the security token", async () => { - let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); await catchRevert(I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); @@ -269,7 +269,7 @@ contract('CountTransferManager', accounts => { assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); - let errorThrown = false; + await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner })); }); @@ -297,7 +297,7 @@ contract('CountTransferManager', accounts => { }); it("Should fail in modifying the holder count", async() => { - let errorThrown = false; + await catchRevert(I_CountTransferManager.changeHolderCount(1, { from: account_investor1 })); }) @@ -324,7 +324,7 @@ contract('CountTransferManager', accounts => { }); it("Should not be able to transfer to a new token holder", async() => { - let errorThrown = false; + // await I_CountTransferManager.unpause({from: token_owner}); await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 })); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 9773398c1..f87920419 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -266,7 +266,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { - let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); await catchRevert(I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); @@ -355,21 +355,21 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Should fail in creating the dividend", async() => { - let errorThrown = false; + let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner})); }); it("Should fail in creating the dividend", async() => { - let errorThrown = false; + let maturity = latestTime(); let expiry = latestTime() - duration.days(10); await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); }); it("Should fail in creating the dividend", async() => { - let errorThrown = false; + let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); @@ -380,7 +380,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Should fail in creating the dividend", async() => { - let errorThrown = false; + let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); @@ -401,19 +401,19 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - let errorThrown = false; + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - let errorThrown = false; + // Increase time by 2 day await increaseTime(duration.days(2)); await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp})); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - let errorThrown = false; + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner})); }); @@ -483,13 +483,13 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Issuer pushes dividends fails due to passed expiry", async() => { - let errorThrown = false; + await increaseTime(duration.days(12)); await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); }); it("Issuer reclaims dividend", async() => { - let errorThrown = false; + let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000})); @@ -535,7 +535,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("should investor 3 claims dividend - fails bad index", async() => { - let errorThrown = false; + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); @@ -563,7 +563,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("should investor 3 claims dividend", async() => { - let errorThrown = false; + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0})); }); @@ -597,7 +597,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Create another new dividend with no value - fails", async() => { - let errorThrown = false; + let maturity = latestTime(); let expiry = latestTime() + duration.days(2); let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); @@ -605,21 +605,21 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Create another new dividend with explicit", async() => { - let errorThrown = false; + let maturity = latestTime(); let expiry = latestTime() - duration.days(10); await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); }); it("Create another new dividend with bad expirty - fails", async() => { - let errorThrown = false; + let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); }); it("Create another new dividend with bad checkpoint in the future - fails", async() => { - let errorThrown = false; + let maturity = latestTime(); let expiry = latestTime() + duration.days(2); await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); @@ -650,7 +650,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Non-owner pushes investor 1 - fails", async() => { - let errorThrown = false; + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); @@ -658,7 +658,7 @@ contract('EtherDividendCheckpoint', accounts => { }); it("issuer pushes investor 1 with bad dividend index - fails", async() => { - let errorThrown = false; + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); @@ -723,12 +723,12 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Issuer unable to reclaim dividend (expiry not passed)", async() => { - let errorThrown = false; + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner})); }); it("Issuer is able to reclaim dividend after expiry", async() => { - let errorThrown = false; + await increaseTime(11 * 24 * 60 * 60); await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0})); }); @@ -741,12 +741,12 @@ contract('EtherDividendCheckpoint', accounts => { }); it("Issuer is able to reclaim dividend after expiry", async() => { - let errorThrown = false; + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0})); }); it("Investor 3 unable to pull dividend after expiry", async() => { - let errorThrown = false; + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0})); }); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 2766728a0..d7b042dd6 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -279,7 +279,7 @@ contract('GeneralPermissionManager', accounts => { }); it("Should successfully attach the General permission manager factory with the security token", async () => { - let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); await catchRevert(I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); @@ -320,12 +320,12 @@ contract('GeneralPermissionManager', accounts => { }); it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async() => { - let errorThrown = false; + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1})); }); it("Should fail to provide the permission-- because delegate is not yet added", async() => { - let errorThrown = false; + await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner})); }); @@ -335,7 +335,7 @@ contract('GeneralPermissionManager', accounts => { }); it("Should fail to provide the permission", async() => { - let errorThrown = false; + await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1})); }); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index f2a5c3fe5..50c587aa4 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -317,7 +317,7 @@ contract('GeneralTransferManager', accounts => { describe("Buy tokens using on-chain whitelist", async() => { it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - let errorThrown = false; + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); }); @@ -350,12 +350,12 @@ contract('GeneralTransferManager', accounts => { }); it("Should fail in buying the token from the STO", async() => { - let errorThrown = false; + await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner })); }); it("Should fail in investing the money in STO -- expiry limit reached", async() => { - let errorThrown = false; + await increaseTime(duration.days(10)); await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); @@ -366,7 +366,7 @@ contract('GeneralTransferManager', accounts => { describe("Buy tokens using off-chain whitelist", async() => { it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - let errorThrown = false; + await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner })); }); @@ -380,7 +380,7 @@ contract('GeneralTransferManager', accounts => { const r = `0x${sig.r.toString('hex')}`; const s = `0x${sig.s.toString('hex')}`; const v = sig.v; - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( account_investor2, @@ -411,7 +411,7 @@ contract('GeneralTransferManager', accounts => { const s = `0x${sig.s.toString('hex')}`; const v = sig.v; - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( account_investor2, fromTime, @@ -441,7 +441,7 @@ contract('GeneralTransferManager', accounts => { const r = `0x${sig.r.toString('hex')}`; const s = `0x${sig.s.toString('hex')}`; const v = sig.v; - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( account_investor2, @@ -503,7 +503,7 @@ contract('GeneralTransferManager', accounts => { }); it("Should fail in changing the signing address", async() => { - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_investor4})); }); @@ -527,13 +527,13 @@ contract('GeneralTransferManager', accounts => { it("Should fail to pull fees as no budget set", async() => { - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); }); it("Should set a budget for the GeneralTransferManager", async() => { await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), {from: token_owner}); - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), {from: token_owner}); @@ -541,7 +541,7 @@ contract('GeneralTransferManager', accounts => { it("Factory owner should pull fees - fails as not permissioned by issuer", async() => { - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate})); }); @@ -569,7 +569,7 @@ contract('GeneralTransferManager', accounts => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], @@ -587,7 +587,7 @@ contract('GeneralTransferManager', accounts => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime], @@ -605,7 +605,7 @@ contract('GeneralTransferManager', accounts => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], @@ -623,7 +623,7 @@ contract('GeneralTransferManager', accounts => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], @@ -641,7 +641,7 @@ contract('GeneralTransferManager', accounts => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - let errorThrown = false; + let tx = await I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index e01de1fa0..b61c44e67 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -334,7 +334,7 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { - let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); await catchRevert(I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); @@ -363,7 +363,7 @@ contract('ManualApprovalTransferManager', accounts => { }); //function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { it("Cannot call verifyTransfer on the TM directly if _isTransfer == true", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { from: token_owner })); }); @@ -409,17 +409,17 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Should fail to add a manual approval because invalid _from address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.addManualApproval("", account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual approval because invalid _to address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, "", web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual approval because invalid expiry time", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { from: token_owner })); }); @@ -428,12 +428,12 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Should fail to revoke manual approval because invalid _from address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner })); }); it("Should fail to revoke manual approval because invalid _to address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, "", { from: token_owner })); }); @@ -477,7 +477,7 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Check further transfers fail", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); //Check that other transfers are still valid @@ -486,17 +486,17 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Should fail to add a manual block because invalid _from address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual block because invalid _to address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { from: token_owner })); }); it("Should fail to add a manual block because invalid expiry time", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner })); }); @@ -505,18 +505,18 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Check manual block causes failure", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); }); it("Should fail to revoke manual block because invalid _from address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking("0x0", account_investor2, { from: token_owner })); }); it("Should fail to revoke manual block because invalid _to address", async() => { - let errorThrown = false; + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, "0x0", { from: token_owner })); }); @@ -531,7 +531,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Check manual block ignored after expiry", async() => { await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); await increaseTime(1 + (24 * 60 * 60)); await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); @@ -563,7 +563,7 @@ contract('ManualApprovalTransferManager', accounts => { // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { // //Should fail initial transfer - // let errorThrown = false; + // // try { // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); // } catch(error) { diff --git a/test/k_module_registry.js b/test/k_module_registry.js index a62be5d15..b301081c5 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -215,7 +215,7 @@ contract('ModuleRegistry', accounts => { describe("Test case for the upgradeFromregistry", async() => { it("Should successfully update the registry contract address -- failed because of bad owner", async() => { - let errorThrown = false; + await catchRevert(I_MRProxied.updateFromRegistry({from: account_temp})); }); @@ -253,7 +253,7 @@ contract('ModuleRegistry', accounts => { it("Should fail to register the module -- when registerModule is paused", async() => { await I_MRProxied.pause({from: account_polymath}); - let errorThrown = false; + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_delegate})); await I_MRProxied.unpause({from: account_polymath}); }) @@ -272,13 +272,13 @@ contract('ModuleRegistry', accounts => { }); it("Should fail the register the module -- Already registered module", async() => { - let errorThrown = false; + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath})); }) it("Should fail in registering the module-- type = 0", async() => { I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - let errorThrown = false; + await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); }); }); @@ -286,7 +286,7 @@ contract('ModuleRegistry', accounts => { describe("Test case for verifyModule", async() => { it("Should fail in calling the verify module. Because msg.sender should be account_polymath", async () => { - let errorThrown = false; + await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); }); @@ -321,7 +321,7 @@ contract('ModuleRegistry', accounts => { }); it("Should fail in verifying the module. Because the module is not registered", async() => { - let errorThrown = false; + await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); }); }) @@ -341,7 +341,7 @@ contract('ModuleRegistry', accounts => { startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner})); }); @@ -355,7 +355,7 @@ contract('ModuleRegistry', accounts => { ); - let errorThrown = false; + await catchRevert(I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner })); }); @@ -403,7 +403,7 @@ contract('ModuleRegistry', accounts => { assert.equal(_lstVersion[2],0); assert.equal(_lstVersion[1],1); let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); await revertToSnapshot(id); }) @@ -426,7 +426,7 @@ contract('ModuleRegistry', accounts => { let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); - let errorThrown = false; + await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); }); @@ -478,7 +478,7 @@ contract('ModuleRegistry', accounts => { describe("Test cases for removeModule()", async() => { it("Should fail if msg.sender not curator or owner", async() => { - let errorThrown = false; + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp })); }); @@ -535,7 +535,7 @@ contract('ModuleRegistry', accounts => { }); it("Should fail if module already removed", async() => { - let errorThrown = false; + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath })); }); @@ -558,7 +558,7 @@ contract('ModuleRegistry', accounts => { describe("Test cases for pausing the contract", async() => { it("Should fail to pause if msg.sender is not owner", async() => { - let errorThrown = false; + await catchRevert(I_MRProxied.pause({ from: account_temp })); }); @@ -569,7 +569,7 @@ contract('ModuleRegistry', accounts => { }); it("Should fail to unpause if msg.sender is not owner", async() => { - let errorThrown = false; + await catchRevert(I_MRProxied.unpause({ from: account_temp })); }); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 7659d33ac..76c623b03 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -250,7 +250,7 @@ contract('PercentageTransferManager', accounts => { }); it("Should successfully attach the PercentageTransferManagerr factory with the security token", async () => { - let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); await catchRevert(I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); }); @@ -327,7 +327,7 @@ contract('PercentageTransferManager', accounts => { }) it("Should not be able to transfer between existing token holders over limit", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 })); }); diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index e43d87c94..edda686f3 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -255,7 +255,7 @@ contract('PreSaleSTO', accounts => { it("Should fail to launch the STO due to endTime is 0", async () => { let bytesSTO = encodeModuleCall(STOParameters, [0]); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); }); @@ -295,7 +295,7 @@ contract('PreSaleSTO', accounts => { describe("Buy tokens", async() => { it("Should allocate the tokens -- failed due to investor not on whitelist", async () => { - let errorThrown = false; + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0)); }); @@ -335,7 +335,7 @@ contract('PreSaleSTO', accounts => { }); it("Should allocate the tokens -- failed due to msg.sender is not pre sale admin", async () => { - let errorThrown = false; + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver })); }); @@ -385,7 +385,7 @@ contract('PreSaleSTO', accounts => { it("Should failed at the time of buying the tokens -- Because STO has started", async() => { await increaseTime(duration.days(100)); // increased beyond the end time of the STO - let errorThrown = false; + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, {from: account_issuer})); }); @@ -398,7 +398,7 @@ contract('PreSaleSTO', accounts => { await I_PolyToken.getTokens(value, account_investor1); await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); - let errorThrown = false; + await catchRevert(I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); }); diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 44d830765..15efa13b9 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -700,7 +700,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should successfully generate the custom token", async() => { // Fulfilling the TickerStatus.NN condition - // let errorThrown = false; + // // await catchRevert(I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath})); // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); // await increaseTime(duration.days(1)); @@ -776,7 +776,7 @@ contract('SecurityTokenRegistry', accounts => { }) it("Should able to transfer the ticker ownership -- failed because new owner is 0x", async() => { - let errorThrown = false; + await I_SecurityToken002.transferOwnership(account_temp, {from: token_owner}); catchRevert( I_STRProxied.transferTickerOwnership("0x00000000000000000000000000000000000000000", symbol2, {from: token_owner}), diff --git a/test/o_security_token.js b/test/o_security_token.js index 594f7d542..021154f8d 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -282,7 +282,7 @@ contract('SecurityToken', accounts => { }); it("Should mint the tokens before attaching the STO -- fail only be called by the owner", async() => { - let errorThrown = false; + let fromTime = latestTime(); let toTime = fromTime + duration.days(100); let expiryTime = toTime + duration.days(100); @@ -308,7 +308,7 @@ contract('SecurityToken', accounts => { }); it("Should mint the multi tokens before attaching the STO -- fail only be called by the owner", async() => { - let errorThrown = false; + let fromTime = latestTime(); let toTime = fromTime + duration.days(100); let expiryTime = toTime + duration.days(100); @@ -329,7 +329,7 @@ contract('SecurityToken', accounts => { }); it("Should mintMulti", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18))], {from: token_owner, gas: 500000})); }) @@ -342,36 +342,34 @@ contract('SecurityToken', accounts => { }); it("Should finish the minting -- fail because feature is not activated", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.freezeMinting({from: token_owner})); }); it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async() => { - let errorThrown = false; + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: token_owner})); }); it("Should finish the minting -- successfully activate the feature", async() => { - let errorThrown1 = false; await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", false, {from: account_polymath})); 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; await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_polymath})); }); it("Should finish the minting -- fail because msg.sender is not the owner", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.freezeMinting({from: account_temp})); }); it("Should finish minting & restrict the further minting", async() => { let id = await takeSnapshot(); await I_SecurityToken.freezeMinting({from: token_owner}); - let errorThrown = false; + await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); await revertToSnapshot(id); }); @@ -380,7 +378,7 @@ contract('SecurityToken', accounts => { startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); @@ -390,7 +388,7 @@ contract('SecurityToken', accounts => { 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}); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner })); }); @@ -418,7 +416,7 @@ contract('SecurityToken', accounts => { 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; + await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); await revertToSnapshot(id); }); @@ -462,7 +460,7 @@ contract('SecurityToken', accounts => { }); it("Should fail in updating the token details", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.updateTokenDetails("new token details", {from: account_delegate})); }); @@ -472,17 +470,17 @@ contract('SecurityToken', accounts => { }); it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp })); }); it("Should fail to remove the module - module not archived", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner })); }) it("Should fail to remove the module - incorrect address", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.removeModule(0, { from : token_owner })); }) @@ -533,13 +531,13 @@ contract('SecurityToken', accounts => { }); it("Should fail to mint tokens while GTM unarchived", async () => { - let errorThrown = false; + await catchRevert(I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); }); it("Should change the budget of the module - fail incorrect address", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.changeModuleBudget(0, (100 * Math.pow(10, 18)),{ from : token_owner})); }); @@ -602,12 +600,12 @@ contract('SecurityToken', accounts => { }); it("Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1})); }); it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { - let errorThrown = false; + // Add permission to the deletgate (A regesteration process) await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: token_owner}); let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); @@ -626,7 +624,7 @@ contract('SecurityToken', accounts => { it("Should fail to activate the bool allowAllTransfer", async() => { - let errorThrown = false; + await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_temp })); }); @@ -639,17 +637,17 @@ contract('SecurityToken', accounts => { it("Should fail to send tokens with the wrong granularity", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1})); }); it("Should adjust granularity", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.changeGranularity(0, {from: token_owner })); }); it("Should adjust granularity", async() => { - let errorThrown = false; + await I_SecurityToken.changeGranularity(Math.pow(10, 17), {from: token_owner }); await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1, gas: 2500000 }); await I_SecurityToken.transfer(account_investor1, Math.pow(10, 17), { from : accounts[7], gas: 2500000}); @@ -734,7 +732,7 @@ contract('SecurityToken', accounts => { }); it("Should Fail in trasferring from whitelist investor1 to non-whitelist investor", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(account_temp, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000})); await revertToSnapshot(ID_snap); }); @@ -804,7 +802,7 @@ 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; + await catchRevert(web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, @@ -830,7 +828,7 @@ contract('SecurityToken', accounts => { }); it("should account_temp fail in buying the token", async() => { - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, @@ -845,7 +843,7 @@ contract('SecurityToken', accounts => { }); it("Should fail to freeze the transfers", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.freezeTransfers({from: token_owner})); }); @@ -863,7 +861,7 @@ contract('SecurityToken', accounts => { assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); - let errorThrown = false; + await catchRevert(web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, @@ -875,7 +873,7 @@ contract('SecurityToken', accounts => { it("Should fail in trasfering the tokens from one user to another", async() => { await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); console.log(await I_SecurityToken.balanceOf(account_investor1)); - let errorThrown = false; + await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp})); }); @@ -885,7 +883,7 @@ contract('SecurityToken', accounts => { }); it("Should freeze the transfers", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.unfreezeTransfers({from: token_owner})); }); @@ -906,7 +904,7 @@ contract('SecurityToken', accounts => { } }); it("Should fail to set controller status because msg.sender not owner", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.setController(account_controller, {from: account_controller})); }); @@ -935,14 +933,14 @@ contract('SecurityToken', accounts => { }); it("Should force burn the tokens - value too high", async ()=> { - let errorThrown = false; + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); let currentInvestorCount = await I_SecurityToken.investorCount(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", { from: account_controller })); }); it("Should force burn the tokens - wrong caller", async ()=> { - let errorThrown = false; + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); let currentInvestorCount = await I_SecurityToken.investorCount(); let currentBalance = await I_SecurityToken.balanceOf(account_temp); @@ -975,7 +973,7 @@ contract('SecurityToken', accounts => { }); it("Should check the balance of investor at checkpoint", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); }); @@ -988,7 +986,7 @@ contract('SecurityToken', accounts => { describe("Withdraw Poly", async() => { it("Should successfully withdraw the poly", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: account_temp})); }) @@ -1000,7 +998,7 @@ contract('SecurityToken', accounts => { }); it("Should successfully withdraw the poly", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), {from: token_owner})); }); }); @@ -1008,17 +1006,16 @@ contract('SecurityToken', accounts => { describe("Force Transfer", async() => { it("Should fail to forceTransfer because not approved controller", async() => { - let errorThrown1 = false; await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_investor1})); }); it("Should fail to forceTransfer because insufficient balance", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); }); it("Should fail to forceTransfer because recipient is zero address", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); }); @@ -1055,12 +1052,12 @@ contract('SecurityToken', accounts => { }); it("Should fail to freeze controller functionality because not owner", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.disableController({from: account_investor1})); }); it("Should fail to freeze controller functionality because disableControllerAllowed not activated", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.disableController({from: token_owner})); }); @@ -1079,17 +1076,17 @@ contract('SecurityToken', accounts => { }); it("Should fail to freeze controller functionality because already frozen", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.disableController({from: token_owner})); }); it("Should fail to set controller because controller functionality frozen", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.setController(account_controller, {from: token_owner})); }); it("Should fail to forceTransfer because controller functionality frozen", async() => { - let errorThrown = false; + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); }); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index c0b42a7fb..1584e7806 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -544,7 +544,7 @@ contract('USDTieredSTO', accounts => { ]; for (var i = 0; i < config.length; i++) { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); } }); @@ -555,7 +555,7 @@ contract('USDTieredSTO', accounts => { let ratePerTier = [BigNumber(10*10**16), BigNumber(0)]; let config = [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); @@ -565,7 +565,7 @@ contract('USDTieredSTO', accounts => { let wallet = "0x0000000000000000000000000000000000000000"; let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], wallet, _reserveWallet[stoId], _usdToken[stoId]]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); @@ -575,7 +575,7 @@ contract('USDTieredSTO', accounts => { let reserveWallet = "0x0000000000000000000000000000000000000000"; let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], reserveWallet]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); @@ -586,7 +586,7 @@ contract('USDTieredSTO', accounts => { let endTime = latestTime() + duration.days(1); let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); @@ -597,7 +597,7 @@ contract('USDTieredSTO', accounts => { let endTime = startTime + duration.days(50); let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let errorThrown = false; + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); }); @@ -653,22 +653,22 @@ contract('USDTieredSTO', accounts => { let snapId = await takeSnapshot(); await increaseTime(duration.days(1)); - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER })); - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15*10**18), BigNumber(1*10**18), { from: ISSUER })); - let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER })); let tempTime1 = latestTime(); let tempTime2 = latestTime() + duration.days(3); - let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER })); - let errorThrown5 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", I_DaiToken.address, { from: ISSUER })); await revertToSnapshot(snapId); @@ -712,11 +712,11 @@ contract('USDTieredSTO', accounts => { await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); // NONACCREDITED ETH - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); }); @@ -744,11 +744,11 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down @@ -756,11 +756,11 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates @@ -1131,27 +1131,27 @@ contract('USDTieredSTO', accounts => { assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); // Buy with ETH NONACCREDITED - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with DAI NONACCREDITED - let errorThrown5 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED - let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED - let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Buy with DAI ACCREDITED - let errorThrown6 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE })); }); @@ -1181,19 +1181,19 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED - let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED - let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down @@ -1201,19 +1201,19 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown5 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown6 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED - let errorThrown7 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED - let errorThrown8 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates @@ -1638,11 +1638,11 @@ contract('USDTieredSTO', accounts => { await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1, gasPrice: GAS_PRICE}); // Buy with ETH NONACCREDITED - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); }); @@ -1672,11 +1672,11 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down @@ -1684,11 +1684,11 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates @@ -1872,19 +1872,19 @@ contract('USDTieredSTO', accounts => { assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); // Buy with ETH NONACCREDITED - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED - let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED - let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); }); @@ -1916,19 +1916,19 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown1 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown2 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED - let errorThrown3 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED - let errorThrown4 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Change exchange rates down @@ -1936,19 +1936,19 @@ contract('USDTieredSTO', accounts => { await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - let errorThrown5 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY NONACCREDITED - let errorThrown6 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); // Buy with ETH ACCREDITED - let errorThrown7 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); // Buy with POLY ACCREDITED - let errorThrown8 = false; + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); // Reset exchange rates diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index 36fa7920d..b41da159e 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -620,7 +620,7 @@ contract('USDTieredSTO Sim', accounts => { let investment_ETH = BigNumber(0.02*10**18); // 10 USD = 0.02 ETH let investment_DAI = BigNumber(10*10**18); // 10 USD = DAI DAI - let errorThrown = false; + await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); } diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 42357b7d8..91ef0c974 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -205,33 +205,33 @@ contract ("SecurityTokenRegistryProxy", accounts => { describe("Upgrade the imlplementation address", async() => { it("Should upgrade the version and implementation address -- fail bad owner", async() => { - let errorThrown = false; + I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({from: account_polymath}); await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_temp})); }); it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { - let errorThrown = false; + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { - let errorThrown = false; + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { - let errorThrown = false; + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistry.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { - let errorThrown = false; + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.0.0", I_SecurityTokenRegistryMock.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { - let errorThrown = false; + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("", I_SecurityTokenRegistryMock.address, {from: account_polymath})); }); @@ -264,12 +264,12 @@ contract ("SecurityTokenRegistryProxy", accounts => { describe("Transfer the ownership of the proxy contract", async() => { it("Should change the ownership of the contract -- because of bad owner", async()=> { - let errorThrown = false; + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); }); it("Should change the ownership of the contract -- new address should not be 0x", async()=> { - let errorThrown = false; + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); }); diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index b3a674f7a..67e6a57a0 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -199,33 +199,33 @@ contract ("ModuleRegistryProxy", accounts => { describe("Upgrade the imlplementation address", async() => { it("Should upgrade the version and implementation address -- fail bad owner", async() => { - let errorThrown = false; + I_MockModuleRegistry = await MockModuleRegistry.new({from: account_polymath}); await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_temp})); }); it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { - let errorThrown = false; + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { - let errorThrown = false; + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); }); it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { - let errorThrown = false; + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_ModuleRegistry.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { - let errorThrown = false; + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.0.0", I_MockModuleRegistry.address, {from: account_polymath})); }); it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { - let errorThrown = false; + await catchRevert(I_ModuleRegistryProxy.upgradeTo("", I_MockModuleRegistry.address, {from: account_polymath})); }); @@ -255,12 +255,12 @@ contract ("ModuleRegistryProxy", accounts => { describe("Transfer the ownership of the proxy contract", async() => { it("Should change the ownership of the contract -- because of bad owner", async()=> { - let errorThrown = false; + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); }); it("Should change the ownership of the contract -- new address should not be 0x", async()=> { - let errorThrown = false; + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); }); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 0f088c0be..1615a5ce1 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -323,7 +323,7 @@ contract('TrackedRedemption', accounts => { it("Redeem some tokens - fail insufficient allowance", async() => { await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - let errorThrown = false; + await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1})); }); From 4e037d6983bb0be041c8dcfff13f053632e33f7a Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 08:57:13 +0530 Subject: [PATCH 058/142] added prettier --- package.json | 4 +- test/a_poly_oracle.js | 530 ++- test/b_capped_sto.js | 1724 ++++---- test/c_checkpoints.js | 543 ++- test/d_count_transfer_manager.js | 646 ++- test/e_erc20_dividends.js | 1671 +++---- test/f_ether_dividends.js | 1633 +++---- test/g_general_permission_manager.js | 663 +-- test/h_general_transfer_manager.js | 1312 +++--- test/helpers/createInstances.js | 218 +- test/helpers/encodeCall.js | 9 +- test/helpers/exceptions.js | 16 +- test/helpers/latestTime.js | 7 +- test/helpers/signData.js | 20 +- test/helpers/testprivateKey.js | 6 +- test/helpers/time.js | 112 +- test/helpers/utils.js | 99 +- test/i_Issuance.js | 643 ++- test/j_manual_approval_transfer_manager.js | 1147 ++--- test/k_module_registry.js | 961 ++-- test/l_percentage_transfer_manager.js | 675 +-- test/m_presale_sto.js | 729 ++- test/n_security_token_registry.js | 2030 ++++----- test/o_security_token.js | 1991 ++++----- test/p_usd_tiered_sto.js | 4654 ++++++++++++-------- test/q_usd_tiered_sto_sim.js | 1536 ++++--- test/r_concurrent_STO.js | 569 ++- test/s_v130_to_v140_upgrade.js | 925 ++-- test/t_security_token_registry_proxy.js | 506 +-- test/u_module_registry_proxy.js | 480 +- test/v_tracked_redemptions.js | 596 ++- 31 files changed, 13730 insertions(+), 12925 deletions(-) diff --git a/package.json b/package.json index 3e06d880f..f7105ee09 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "flatten-oracles": "sol-merger './contracts/oracles/*.sol' ./flat/oracles", "flatten": "sol-merger './contracts/*.sol' ./flat", "ethereum-bridge": "node_modules/.bin/ethereum-bridge -H localhost:8545 -a 9 --dev", - "st20generator": "node demo/ST20Generator" + "st20generator": "node demo/ST20Generator", + "pretty": "prettier --write --single-quote --print-width 140 --tab-width 2 \"**/*.js\"" }, "repository": { "type": "git", @@ -71,6 +72,7 @@ "devDependencies": { "@soldoc/soldoc": "^0.4.3", "eslint": "^4.19.1", + "prettier": "^1.14.3", "eslint-config-standard": "^11.0.0", "eslint-plugin-import": "^2.10.0", "eslint-plugin-node": "^6.0.1", diff --git a/test/a_poly_oracle.js b/test/a_poly_oracle.js index da8268238..dcbe8d563 100644 --- a/test/a_poly_oracle.js +++ b/test/a_poly_oracle.js @@ -1,283 +1,267 @@ const PolyOracle = artifacts.require('./MockPolyOracle.sol'); import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import {increaseTime} from './helpers/time'; +import { increaseTime } from './helpers/time'; import { catchRevert } from './helpers/exceptions'; const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('PolyOracle', accounts=> { - -let I_PolyOracle; -let owner; -const URL = '[URL] json(https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?id=2496&convert=USD&CMC_PRO_API_KEY=${[decrypt] BBObnGOy63qVI3OR2+MX88dzSMVjQboiZc7Wluuh2ngkSgiX1csxWgbAFtu22jbrry42zwCS4IUmer1Wk+1o1XhF7hyspoGCkbufQqYwuUYwcA2slX6RbEDai7NgdkgNGWSwd6DcuN8jD5ZMTkX68rJKkplr}).data."2496".quote.USD.price'; -const alternateURL = "json(https://min-api.cryptocompare.com/data/price?fsym=POLY&tsyms=USD).USD"; -const SanityBounds = 20*10**16; -const GasLimit = 100000; -const TimeTolerance = 5*60; -const message = "Txn should fail"; -let latestPrice; -let requestIds = new Array(); - - before(async()=> { - owner = accounts[0]; - I_PolyOracle = await PolyOracle.new({from : owner}); +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port + +contract('PolyOracle', accounts => { + let I_PolyOracle; + let owner; + const URL = + '[URL] json(https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?id=2496&convert=USD&CMC_PRO_API_KEY=${[decrypt] BBObnGOy63qVI3OR2+MX88dzSMVjQboiZc7Wluuh2ngkSgiX1csxWgbAFtu22jbrry42zwCS4IUmer1Wk+1o1XhF7hyspoGCkbufQqYwuUYwcA2slX6RbEDai7NgdkgNGWSwd6DcuN8jD5ZMTkX68rJKkplr}).data."2496".quote.USD.price'; + const alternateURL = 'json(https://min-api.cryptocompare.com/data/price?fsym=POLY&tsyms=USD).USD'; + const SanityBounds = 20 * 10 ** 16; + const GasLimit = 100000; + const TimeTolerance = 5 * 60; + const message = 'Txn should fail'; + let latestPrice; + let requestIds = new Array(); + + before(async () => { + owner = accounts[0]; + I_PolyOracle = await PolyOracle.new({ from: owner }); + }); + + describe('state variables checks', async () => { + it('should set and check the api url', async () => { + await I_PolyOracle.setOracleURL(URL, { from: owner }); + let url = await I_PolyOracle.oracleURL.call(); + assert.equal(URL, url); }); + it('should check the sanity bounds', async () => { + let sanityBounds = await I_PolyOracle.sanityBounds.call(); + assert.equal(SanityBounds, sanityBounds); + }); + + it('should check the gas limits', async () => { + let gasLimit = await I_PolyOracle.gasLimit.call(); + assert.equal(GasLimit, gasLimit); + }); + + it('should check the oraclize time tolerance', async () => { + let timeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); + assert.equal(TimeTolerance, timeTolerance); + }); + }); + + describe('Scheduling test cases', async () => { + it('Should schedule the timing of the call - fails - non owner', async () => { + let timeScheduling = [latestTime() + duration.minutes(1), latestTime() + duration.minutes(2), latestTime() + duration.minutes(3)]; + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: accounts[1], value: web3.utils.toWei('2') })); + }); + + it('Should schedule the timing of the call - fails - no value', async () => { + let timeScheduling = [latestTime() + duration.minutes(1), latestTime() + duration.minutes(2), latestTime() + duration.minutes(3)]; + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner })); + }); + + it('Should schedule the timing of the call - single call', async () => { + let blockNo = latestBlock(); + let tx = await I_PolyOracle.schedulePriceUpdatesFixed([], { from: owner, value: web3.utils.toWei('1') }); + assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); + // await increaseTime(50); + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); + // const log = await logNewPriceWatcher; + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.'); + assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.'); + assert.equal(logNewPriceWatcher.args._oldPrice.toNumber(), 0); + console.log( + 'Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY' + ); + }); + + it('Should schedule the timing of the call - multiple calls', async () => { + let blockNo = latestBlock(); + let timeScheduling = [latestTime() + duration.seconds(10), latestTime() + duration.seconds(20)]; + let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner, value: web3.utils.toWei('1.5') }); + + let event_data = tx.logs; + + for (var i = 0; i < event_data.length; i++) { + let time = event_data[i].args._time; + console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); + assert.isAtMost(time.toNumber(), timeScheduling[i]); + } + + // Wait for the callback to be invoked by oraclize and the event to be emitted + const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); + const log = await logNewPriceWatcher; + assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.'); + assert.isNotNull(log.args._price, 'Price returned was null.'); + console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + }); + + it('Should schedule to call using iters - fails', async () => { + await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, { from: accounts[6] })); + }); + + it('Should schedule to call using iters', async () => { + let blockNo = latestBlock(); + console.log(`Latest Block number of the local chain:${blockNo}`); + let tx = await I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 10, 2, { from: owner }); + let event_data = tx.logs; + for (var i = 0; i < event_data.length; i++) { + let time = event_data[i].args._time; + requestIds.push(event_data[i].args._queryId); + console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); + assert.isAtMost(time.toNumber(), latestTime() + (i + 1) * 30); + } + // Wait for the callback to be invoked by oraclize and the event to be emitted + const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); + const log = await logNewPriceWatcher; + assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.'); + assert.isNotNull(log.args._price, 'Price returned was null.'); + console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + latestPrice = log.args._price; + }); + }); + + describe('Ownable functions', async () => { + it('Should change the Poly USD price manually - fail - bad account', async () => { + await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), { from: accounts[5] })); + }); + + it('Should change the Poly USD price manually', async () => { + await I_PolyOracle.setPOLYUSD(latestPrice.add(1), { from: owner }); + let price2 = await I_PolyOracle.getPriceAndTime.call(); + assert.equal(price2[0].toNumber(), latestPrice.add(1).toNumber()); + }); + + it('Should freeze the Oracle manually', async () => { + await catchRevert(I_PolyOracle.setFreezeOracle(true, { from: accounts[5] })); + }); + + it('Should change the URL manually', async () => { + let freeze_ = await I_PolyOracle.freezeOracle.call(); + await I_PolyOracle.setFreezeOracle(true, { from: owner }); + let freeze = await I_PolyOracle.freezeOracle.call(); + assert.isFalse(freeze_); + assert.isTrue(freeze); + await I_PolyOracle.setFreezeOracle(false, { from: owner }); + }); + + it('Should change the sanity bounds manually - fails - bad owner', async () => { + await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), { from: accounts[6] })); + }); + + it('Should change the sanity bounds manually', async () => { + console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); + await I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), { from: owner }); + let sanityBounds = await I_PolyOracle.sanityBounds.call(); + console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); + assert.equal(sanityBounds.toNumber(), new BigNumber(25).times(new BigNumber(10).pow(16)).toNumber()); + }); + + it('Should change the gas price manually - fails - bad owner', async () => { + await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)), { from: accounts[6] })); + }); - describe("state variables checks", async() => { - - it("should set and check the api url", async() => { - await I_PolyOracle.setOracleURL(URL, {from: owner}); - let url = await I_PolyOracle.oracleURL.call(); - assert.equal(URL, url); - }); - - it("should check the sanity bounds", async() => { - let sanityBounds = await I_PolyOracle.sanityBounds.call(); - assert.equal(SanityBounds, sanityBounds); - }); - - it("should check the gas limits", async() => { - let gasLimit = await I_PolyOracle.gasLimit.call(); - assert.equal(GasLimit, gasLimit); - }); - - it("should check the oraclize time tolerance", async() => { - let timeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); - assert.equal(TimeTolerance, timeTolerance); - }); - - }) - - describe("Scheduling test cases", async() => { - - it("Should schedule the timing of the call - fails - non owner", async() => { - - let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] - await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: accounts[1], value: web3.utils.toWei("2")})); - }); - - it("Should schedule the timing of the call - fails - no value", async() => { - - let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] - await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner})); - }) - - it("Should schedule the timing of the call - single call", async() => { - let blockNo = latestBlock(); - let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); - assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); - // await increaseTime(50); - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); - // const log = await logNewPriceWatcher; - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') - assert.equal(logNewPriceWatcher.args._oldPrice.toNumber(), 0); - console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') - - }); - - it("Should schedule the timing of the call - multiple calls", async() => { - let blockNo = latestBlock(); - let timeScheduling = [latestTime()+duration.seconds(10), latestTime()+duration.seconds(20)] - let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner, value:web3.utils.toWei("1.5")}); - - let event_data = tx.logs; - - for (var i = 0; i < event_data.length; i++) { - let time = event_data[i].args._time; - console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); - assert.isAtMost(time.toNumber(), timeScheduling[i]); - } - - // Wait for the callback to be invoked by oraclize and the event to be emitted - const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - const log = await logNewPriceWatcher; - assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(log.args._price, 'Price returned was null.'); - console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') - }); - - it("Should schedule to call using iters - fails", async() => { - - await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, {from: accounts[6]})); - }) - - it("Should schedule to call using iters", async() => { - let blockNo = latestBlock(); - console.log(`Latest Block number of the local chain:${blockNo}`); - let tx = await I_PolyOracle.schedulePriceUpdatesRolling(latestTime()+10, 10, 2, {from: owner}); - let event_data = tx.logs; - for (var i = 0; i < event_data.length; i++) { - let time = event_data[i].args._time; - requestIds.push(event_data[i].args._queryId); - console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); - assert.isAtMost(time.toNumber(), latestTime() + ((i + 1) * 30)); - } - // Wait for the callback to be invoked by oraclize and the event to be emitted - const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - const log = await logNewPriceWatcher; - assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(log.args._price, 'Price returned was null.') - console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); - latestPrice = log.args._price; - }); - }) - - describe("Ownable functions", async() => { - - it("Should change the Poly USD price manually - fail - bad account", async() => { - - await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: accounts[5]})); - }); - - it("Should change the Poly USD price manually", async() => { - await I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: owner}); - let price2 = await I_PolyOracle.getPriceAndTime.call(); - assert.equal(price2[0].toNumber(), latestPrice.add(1).toNumber()); - }) - - it("Should freeze the Oracle manually", async() => { - - await catchRevert(I_PolyOracle.setFreezeOracle(true, {from: accounts[5]})); - }) - - it("Should change the URL manually", async() => { - let freeze_ = await I_PolyOracle.freezeOracle.call(); - await I_PolyOracle.setFreezeOracle(true, {from: owner}); - let freeze = await I_PolyOracle.freezeOracle.call(); - assert.isFalse(freeze_); - assert.isTrue(freeze); - await I_PolyOracle.setFreezeOracle(false, {from: owner}); - }) - - it("Should change the sanity bounds manually - fails - bad owner", async() => { - - await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : accounts[6]})); - }) - - it("Should change the sanity bounds manually", async() => { - console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); - await I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : owner}); - let sanityBounds = await I_PolyOracle.sanityBounds.call(); - console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); - assert.equal(sanityBounds.toNumber(), new BigNumber(25).times(new BigNumber(10).pow(16)).toNumber()) - }); - - it("Should change the gas price manually - fails - bad owner", async() => { - - await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : accounts[6]})); - }); - - it("Should change the gas price manually", async() => { - await I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : owner}); - let blockNo = latestBlock(); - let timeScheduling = [latestTime()+duration.seconds(10), latestTime()+duration.seconds(20)]; - let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner, value:web3.utils.toWei("2")}); - - let event_data = tx.logs; - - for (var i = 0; i < event_data.length; i++) { - let time = event_data[i].args._time; - console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); - assert.isAtMost(time.toNumber(), timeScheduling[i]); - } - - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') - console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); - // assert.isTrue(false); - - }); - - it("Should change the gas limit manually - fails", async() => { - - await catchRevert(I_PolyOracle.setGasLimit(50000,{from : accounts[6]})); - }); - - it("Should change the gas limit manually", async() => { - await I_PolyOracle.setGasLimit(50000,{from : owner}); - let gasLimit = await I_PolyOracle.gasLimit.call(); - assert.equal(gasLimit.toNumber(),50000); - await I_PolyOracle.setGasLimit(100000,{from : owner}); - }); - - it("Should blacklist some IDS manually - fails - wrong size", async() => { - - let ignore = [true]; - await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds,ignore,{from : accounts[6]})); - }); - - it("Should blacklist some IDS manually", async() => { - let ignore = [false, true]; - console.log(requestIds); - await I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, {from : owner}); - - // let ignoreRequestId0 = await I_PolyOracle.ignoreRequestIds.call(requestIds[1]); - // assert.equal(ignoreRequestId0,true); - - // let ignoreRequestId1 = await I_PolyOracle.ignoreRequestIds.call(requestIds[2]); - // assert.equal(ignoreRequestId1,false); - - }); - - it("Should change the oraclize time tolerance manually - fails", async() => { - - await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600,{from : accounts[6]})); - }) - - it("Should change the oraclize time tolerance manually", async() => { - await I_PolyOracle.setOraclizeTimeTolerance(3600,{from : owner}); - let oraclizeTimeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); - assert.equal(oraclizeTimeTolerance.toNumber(),3600); - }); - - it("should change the api URL manually", async() => { - - await catchRevert(I_PolyOracle.setOracleURL(alternateURL, {from: accounts[6]})); - }) - - it("should change the api URL manually", async() => { - await I_PolyOracle.setOracleURL(alternateURL, {from: owner}); - await I_PolyOracle.setOracleQueryType("URL", {from: owner}); - let url = await I_PolyOracle.oracleURL.call(); - assert.equal(alternateURL, url); - }); - - it("Should schedule the timing of the call - after changes", async() => { - let blockNo = latestBlock(); - let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); - assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') - console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); - // assert.isTrue(false); - }); - - }) - - describe("Get Functions call", async() => { - it("Should get the currency address", async() => { - let polyTokenAddress = await I_PolyOracle.getCurrencyAddress.call(); - assert.equal(polyTokenAddress, ("0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC").toLowerCase()); - }); - - it("Should get the currency symbol", async() => { - let currency = await I_PolyOracle.getCurrencySymbol.call(); - assert.equal(web3.utils.toAscii(currency).replace(/\u0000/g, ''), "POLY"); - }); - - it("Should get the currency denomination", async() => { - let denomination = await I_PolyOracle.getCurrencyDenominated.call(); - assert.equal(web3.utils.toAscii(denomination).replace(/\u0000/g, ''), "USD"); - }) - - }) - -}) + it('Should change the gas price manually', async () => { + await I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)), { from: owner }); + let blockNo = latestBlock(); + let timeScheduling = [latestTime() + duration.seconds(10), latestTime() + duration.seconds(20)]; + let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner, value: web3.utils.toWei('2') }); + + let event_data = tx.logs; + + for (var i = 0; i < event_data.length; i++) { + let time = event_data[i].args._time; + console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); + assert.isAtMost(time.toNumber(), timeScheduling[i]); + } + + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); + + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.'); + assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.'); + console.log( + 'Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY' + ); + // assert.isTrue(false); + }); + + it('Should change the gas limit manually - fails', async () => { + await catchRevert(I_PolyOracle.setGasLimit(50000, { from: accounts[6] })); + }); + + it('Should change the gas limit manually', async () => { + await I_PolyOracle.setGasLimit(50000, { from: owner }); + let gasLimit = await I_PolyOracle.gasLimit.call(); + assert.equal(gasLimit.toNumber(), 50000); + await I_PolyOracle.setGasLimit(100000, { from: owner }); + }); + + it('Should blacklist some IDS manually - fails - wrong size', async () => { + let ignore = [true]; + await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, { from: accounts[6] })); + }); + + it('Should blacklist some IDS manually', async () => { + let ignore = [false, true]; + console.log(requestIds); + await I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, { from: owner }); + + // let ignoreRequestId0 = await I_PolyOracle.ignoreRequestIds.call(requestIds[1]); + // assert.equal(ignoreRequestId0,true); + + // let ignoreRequestId1 = await I_PolyOracle.ignoreRequestIds.call(requestIds[2]); + // assert.equal(ignoreRequestId1,false); + }); + + it('Should change the oraclize time tolerance manually - fails', async () => { + await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600, { from: accounts[6] })); + }); + + it('Should change the oraclize time tolerance manually', async () => { + await I_PolyOracle.setOraclizeTimeTolerance(3600, { from: owner }); + let oraclizeTimeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); + assert.equal(oraclizeTimeTolerance.toNumber(), 3600); + }); + + it('should change the api URL manually', async () => { + await catchRevert(I_PolyOracle.setOracleURL(alternateURL, { from: accounts[6] })); + }); + + it('should change the api URL manually', async () => { + await I_PolyOracle.setOracleURL(alternateURL, { from: owner }); + await I_PolyOracle.setOracleQueryType('URL', { from: owner }); + let url = await I_PolyOracle.oracleURL.call(); + assert.equal(alternateURL, url); + }); + + it('Should schedule the timing of the call - after changes', async () => { + let blockNo = latestBlock(); + let tx = await I_PolyOracle.schedulePriceUpdatesFixed([], { from: owner, value: web3.utils.toWei('1') }); + assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.'); + assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.'); + console.log( + 'Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY' + ); + // assert.isTrue(false); + }); + }); + + describe('Get Functions call', async () => { + it('Should get the currency address', async () => { + let polyTokenAddress = await I_PolyOracle.getCurrencyAddress.call(); + assert.equal(polyTokenAddress, '0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC'.toLowerCase()); + }); + + it('Should get the currency symbol', async () => { + let currency = await I_PolyOracle.getCurrencySymbol.call(); + assert.equal(web3.utils.toAscii(currency).replace(/\u0000/g, ''), 'POLY'); + }); + + it('Should get the currency denomination', async () => { + let denomination = await I_PolyOracle.getCurrencyDenominated.call(); + assert.equal(web3.utils.toAscii(denomination).replace(/\u0000/g, ''), 'USD'); + }); + }); +}); diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 6bc815bdc..0554ddf0f 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -14,143 +14,152 @@ const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager') const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port let ETH = 0; let POLY = 1; let DAI = 2; contract('CappedSTO', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_investor3; - let account_fundsReceiver; - - let balanceOfReceiver; - let message = "Transaction Should Fail!"; - // investor Details - let fromTime; - let toTime; - let expiryTime; - let P_fromTime; - let P_toTime; - let P_expiryTime; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_SecurityTokenRegistry; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_FeatureRegistry; - let I_CappedSTOFactory; - let I_STFactory; - let I_SecurityToken_ETH; - let I_SecurityToken_POLY; - let I_CappedSTO_Array_ETH = []; - let I_CappedSTO_Array_POLY = []; - let I_PolyToken; - let I_PolymathRegistry; - let I_STRProxied; - let I_MRProxied; - let pauseTime; - - // SecurityToken Details for funds raise Type ETH - const name = "Team"; - const symbol = "SAP"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - - // SecurityToken Details for funds raise Type POLY - const P_name = "Team Poly"; - const P_symbol = "PAS"; - const P_tokenDetails = "This is equity type of issuance"; - const P_decimals = 18; - - // Module key - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // Capped STO details - let startTime_ETH1; - let endTime_ETH1; - let startTime_ETH2; - let endTime_ETH2; - const cap = web3.utils.toWei("10000"); - const rate = 1000; - const E_fundRaiseType = 0; - - let startTime_POLY1; - let endTime_POLY1; - let startTime_POLY2; - let endTime_POLY2; - let blockNo; - const P_cap = web3.utils.toWei("50000"); - const P_fundRaiseType = 1; - const P_rate = 5; - const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); - const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[4]; - account_investor2 = accounts[3]; - account_investor3 = accounts[5] - account_fundsReceiver = accounts[2]; - token_owner = account_issuer; - - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 6: Deploy the CappedSTOFactory - - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); - - - // STEP 7: Register the Modules with the ModuleRegistry contract - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_investor3; + let account_fundsReceiver; + + let balanceOfReceiver; + let message = 'Transaction Should Fail!'; + // investor Details + let fromTime; + let toTime; + let expiryTime; + let P_fromTime; + let P_toTime; + let P_expiryTime; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_SecurityTokenRegistry; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_FeatureRegistry; + let I_CappedSTOFactory; + let I_STFactory; + let I_SecurityToken_ETH; + let I_SecurityToken_POLY; + let I_CappedSTO_Array_ETH = []; + let I_CappedSTO_Array_POLY = []; + let I_PolyToken; + let I_PolymathRegistry; + let I_STRProxied; + let I_MRProxied; + let pauseTime; + + // SecurityToken Details for funds raise Type ETH + const name = 'Team'; + const symbol = 'SAP'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + // SecurityToken Details for funds raise Type POLY + const P_name = 'Team Poly'; + const P_symbol = 'PAS'; + const P_tokenDetails = 'This is equity type of issuance'; + const P_decimals = 18; + + // Module key + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // Capped STO details + let startTime_ETH1; + let endTime_ETH1; + let startTime_ETH2; + let endTime_ETH2; + const cap = web3.utils.toWei('10000'); + const rate = 1000; + const E_fundRaiseType = 0; + + let startTime_POLY1; + let endTime_POLY1; + let startTime_POLY2; + let endTime_POLY2; + let blockNo; + const P_cap = web3.utils.toWei('50000'); + const P_fundRaiseType = 1; + const P_rate = 5; + const cappedSTOSetupCost = web3.utils.toWei('20000', 'ether'); + const maxCost = cappedSTOSetupCost; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[4]; + account_investor2 = accounts[3]; + account_investor3 = accounts[5]; + account_fundsReceiver = accounts[2]; + token_owner = account_issuer; + + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 5: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); + + // STEP 6: Deploy the CappedSTOFactory + + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); + + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CappedSTOFactory contract was not deployed' + ); + + // STEP 7: Register the Modules with the ModuleRegistry contract + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -166,909 +175,748 @@ contract('CappedSTO', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol); }); - describe("Generate the SecurityToken", async() => { + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol); - }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + I_SecurityToken_ETH = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + const log = await promisifyLogWatch(I_SecurityToken_ETH.ModuleAdded({ from: _blockNo }), 1); - I_SecurityToken_ETH = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); + }); + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken_ETH.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); - const log = await promisifyLogWatch(I_SecurityToken_ETH.ModuleAdded({from: _blockNo}), 1); + it('Should mint the tokens before attaching the STO', async () => { + await catchRevert( + I_SecurityToken_ETH.mint('0x0000000000000000000000000000000000000000', web3.utils.toWei('1'), { from: token_owner }) + ); + }); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); - }); + it("Should fail to launch the STO due to security token doesn't have the sufficient POLY", async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken_ETH.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - it("Should mint the tokens before attaching the STO", async() => { - - await catchRevert(I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), {from: token_owner})); - }); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - it("Should fail to launch the STO due to security token doesn't have the sufficient POLY", async () => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + it('Should fail to launch the STO due to rate is 0', async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - it("Should fail to launch the STO due to rate is 0", async () => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner}); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + it('Should fail to launch the STO due to startTime > endTime', async () => { + let bytesSTO = encodeModuleCall(STOParameters, [ + Math.floor(Date.now() / 1000 + 100000), + Math.floor(Date.now() / 1000 + 1000), + cap, + rate, + [E_fundRaiseType], + account_fundsReceiver + ]); + + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - it("Should fail to launch the STO due to startTime > endTime", async () => { - let bytesSTO = encodeModuleCall(STOParameters, [ Math.floor(Date.now()/1000 + 100000), Math.floor(Date.now()/1000 + 1000), cap, rate, [E_fundRaiseType], account_fundsReceiver]); - - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + it('Should fail to launch the STO due to cap is of 0 securityToken', async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); - it("Should fail to launch the STO due to cap is of 0 securityToken", async () => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [ startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); - - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - it("Should successfully attach the STO module to the security token", async () => { - startTime_ETH1 = latestTime() + duration.days(1); - endTime_ETH1 = startTime_ETH1 + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver]); - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + it('Should successfully attach the STO module to the security token', async () => { + startTime_ETH1 = latestTime() + duration.days(1); + endTime_ETH1 = startTime_ETH1 + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); - I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); - }); + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); + I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); + }); + }); + + describe('verify the data of STO', async () => { + it('Should verify the configuration of the STO', async () => { + assert.equal(await I_CappedSTO_Array_ETH[0].startTime.call(), startTime_ETH1, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[0].endTime.call(), endTime_ETH1, "STO Configuration doesn't set as expected"); + assert.equal((await I_CappedSTO_Array_ETH[0].cap.call()).toNumber(), cap, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[0].rate.call(), rate, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[0].fundRaiseTypes.call(E_fundRaiseType), true, "STO Configuration doesn't set as expected"); + }); + }); + + describe('Buy tokens', async () => { + it('Should buy the tokens -- failed due to startTime is greater than Current time', async () => { + await catchRevert( + web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('1', 'ether') + }) + ); }); - describe("verify the data of STO", async () => { - - it("Should verify the configuration of the STO", async() => { - assert.equal( - await I_CappedSTO_Array_ETH[0].startTime.call(), - startTime_ETH1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[0].endTime.call(), - endTime_ETH1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_ETH[0].cap.call()).toNumber(), - cap, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[0].rate.call(), - rate, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[0].fundRaiseTypes.call(E_fundRaiseType), - true, - "STO Configuration doesn't set as expected" - ); - }); + it('Should buy the tokens -- failed due to invested amount is zero', async () => { + await catchRevert( + web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('0', 'ether') + }) + ); }); - describe("Buy tokens", async() => { + it('Should buy the tokens -- Failed due to investor is not in the whitelist', async () => { + await catchRevert( + web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('1', 'ether') + }) + ); + }); - it("Should buy the tokens -- failed due to startTime is greater than Current time", async () => { - - await catchRevert(web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('1', 'ether') - })); - }); + it('Should buy the tokens -- Failed due to wrong granularity', async () => { + await catchRevert( + web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('0.1111', 'ether') + }) + ); + }); - it("Should buy the tokens -- failed due to invested amount is zero", async () => { - - await catchRevert(web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0', 'ether') - })); - }); + it('Should Buy the tokens', async () => { + blockNo = latestBlock(); + fromTime = latestTime(); + toTime = latestTime() + duration.days(15); + expiryTime = toTime + duration.days(100); + P_fromTime = fromTime + duration.days(1); + P_toTime = P_fromTime + duration.days(50); + P_expiryTime = toTime + duration.days(100); - it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - - await catchRevert(web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('1', 'ether') - })); - }); + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + // Add the Investor in to the whitelist - it("Should buy the tokens -- Failed due to wrong granularity", async () => { - - await catchRevert(web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0.1111', 'ether') - })); - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 500000 + }); - it("Should Buy the tokens", async() => { - blockNo = latestBlock(); - fromTime = latestTime(); - toTime = latestTime() + duration.days(15); - expiryTime = toTime + duration.days(100); - P_fromTime = fromTime + duration.days(1); - P_toTime = P_fromTime + duration.days(50); - P_expiryTime = toTime + duration.days(100); - - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(duration.days(1)); - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); - - assert.equal( - (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); - - assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 1); - - assert.equal( - (await I_SecurityToken_ETH.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }); + assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); - it("Verification of the event Token Purchase", async() => { - const log = await promisifyLogWatch(I_CappedSTO_Array_ETH[0].TokenPurchase({from: blockNo}), 1); - - assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); - assert.equal( - (log.args.amount) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000, - "Wrong No. token get dilivered" - ); - }); + // Jump time + await increaseTime(duration.days(1)); + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }); - it("Should pause the STO -- Failed due to wrong msg.sender", async()=> { - - await catchRevert(I_CappedSTO_Array_ETH[0].pause({from: account_investor1})); - }); + assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - it("Should pause the STO", async()=> { - pauseTime = latestTime(); - let tx = await I_CappedSTO_Array_ETH[0].pause({from: account_issuer}); - assert.isTrue(await I_CappedSTO_Array_ETH[0].paused.call()); - }); + assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 1); - it("Should fail to buy the tokens after pausing the STO", async() => { - - await catchRevert(web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); - }); + assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); - it("Should unpause the STO -- Failed due to wrong msg.sender", async()=> { - - await catchRevert(I_CappedSTO_Array_ETH[0].unpause({from: account_investor1})); - }); + it('Verification of the event Token Purchase', async () => { + const log = await promisifyLogWatch(I_CappedSTO_Array_ETH[0].TokenPurchase({ from: blockNo }), 1); - it("Should unpause the STO", async()=> { - let tx = await I_CappedSTO_Array_ETH[0].unpause({from: account_issuer}); - assert.isFalse(await I_CappedSTO_Array_ETH[0].paused.call()); - }); + assert.equal(log.args.purchaser, account_investor1, 'Wrong address of the investor'); + assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000, 'Wrong No. token get dilivered'); + }); - it("Should buy the tokens -- Failed due to wrong granularity", async () => { - - await catchRevert(web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0.1111', 'ether') - })); - }); + it('Should pause the STO -- Failed due to wrong msg.sender', async () => { + await catchRevert(I_CappedSTO_Array_ETH[0].pause({ from: account_investor1 })); + }); - it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - fromTime, - toTime + duration.days(20), - expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO_Array_ETH[0].address, - gas: 2100000, - value: web3.utils.toWei('9', 'ether') - }); - - assert.equal( - (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 10 - ); - - assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 2); - - assert.equal( - (await I_SecurityToken_ETH.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 9000 - ); - await catchRevert(web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO_Array_ETH[0].address, - gas: 210000, - value: web3.utils.toWei('1', 'ether') - })); - }); + it('Should pause the STO', async () => { + pauseTime = latestTime(); + let tx = await I_CappedSTO_Array_ETH[0].pause({ from: account_issuer }); + assert.isTrue(await I_CappedSTO_Array_ETH[0].paused.call()); + }); - it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { - const newBalance = await web3.eth.getBalance(account_fundsReceiver); - //console.log("WWWW",newBalance,await I_CappedSTO.fundsRaised.call(),balanceOfReceiver); - let op = (BigNumber(newBalance).minus(balanceOfReceiver)).toNumber(); - assert.equal( - (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).toNumber(), - op, - "Somewhere raised money get stolen or sent to wrong wallet" - ); - }); + it('Should fail to buy the tokens after pausing the STO', async () => { + await catchRevert( + web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }) + ); + }); - it("Should get the raised amount of ether", async() => { - assert.equal(await I_CappedSTO_Array_ETH[0].getRaised.call(ETH), web3.utils.toWei('10','ether')); - }); + it('Should unpause the STO -- Failed due to wrong msg.sender', async () => { + await catchRevert(I_CappedSTO_Array_ETH[0].unpause({ from: account_investor1 })); + }); - it("Should get the raised amount of poly", async() => { - assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('0','ether')); - }); + it('Should unpause the STO', async () => { + let tx = await I_CappedSTO_Array_ETH[0].unpause({ from: account_issuer }); + assert.isFalse(await I_CappedSTO_Array_ETH[0].paused.call()); + }); + it('Should buy the tokens -- Failed due to wrong granularity', async () => { + await catchRevert( + web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('0.1111', 'ether') + }) + ); }); - describe("Reclaim poly sent to STO by mistake", async() => { + it('Should restrict to buy tokens after hiting the cap in second tx first tx pass', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime + duration.days(20), expiryTime, true, { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); + + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor2, + to: I_CappedSTO_Array_ETH[0].address, + gas: 2100000, + value: web3.utils.toWei('9', 'ether') + }); + + assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10); + + assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 2); + + assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 9000); + await catchRevert( + web3.eth.sendTransaction({ + from: account_investor2, + to: I_CappedSTO_Array_ETH[0].address, + gas: 210000, + value: web3.utils.toWei('1', 'ether') + }) + ); + }); - it("Should fail to reclaim POLY because token contract address is 0 address", async() => { - let value = web3.utils.toWei('100','ether'); - await I_PolyToken.getTokens(value, account_investor1); - await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); + it('Should fundRaised value equal to the raised value in the funds receiver wallet', async () => { + const newBalance = await web3.eth.getBalance(account_fundsReceiver); + //console.log("WWWW",newBalance,await I_CappedSTO.fundsRaised.call(),balanceOfReceiver); + let op = BigNumber(newBalance) + .minus(balanceOfReceiver) + .toNumber(); + assert.equal( + (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).toNumber(), + op, + 'Somewhere raised money get stolen or sent to wrong wallet' + ); + }); - - await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); - }); + it('Should get the raised amount of ether', async () => { + assert.equal(await I_CappedSTO_Array_ETH[0].getRaised.call(ETH), web3.utils.toWei('10', 'ether')); + }); - it("Should successfully reclaim POLY", async() => { - let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); - let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); - let initContractBalance = await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address); - let value = web3.utils.toWei('100','ether'); - - await I_PolyToken.getTokens(value, account_investor1); - await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); - await I_CappedSTO_Array_ETH[0].reclaimERC20(I_PolyToken.address, { from: token_owner }); - assert.equal((await I_PolyToken.balanceOf(account_investor3)).toNumber(), initInvestorBalance.toNumber(), "tokens are not transfered out from investor account"); - assert.equal((await I_PolyToken.balanceOf(token_owner)).toNumber(), initOwnerBalance.add(value).add(initContractBalance).toNumber(), "tokens are not added to the owner account"); - assert.equal((await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address)).toNumber(), 0, "tokens are not trandfered out from STO contract"); - }); + it('Should get the raised amount of poly', async () => { + assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('0', 'ether')); }); + }); - describe("Attach second ETH STO module", async() => { + describe('Reclaim poly sent to STO by mistake', async () => { + it('Should fail to reclaim POLY because token contract address is 0 address', async () => { + let value = web3.utils.toWei('100', 'ether'); + await I_PolyToken.getTokens(value, account_investor1); + await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); - it("Should successfully attach the second STO module to the security token", async () => { - startTime_ETH2 = latestTime() + duration.days(1); - endTime_ETH2 = startTime_ETH2 + duration.days(30); + await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); + }); - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner}); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH2, endTime_ETH2, cap, rate, [E_fundRaiseType], account_fundsReceiver]); - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + it('Should successfully reclaim POLY', async () => { + let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); + let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); + let initContractBalance = await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address); + let value = web3.utils.toWei('100', 'ether'); + + await I_PolyToken.getTokens(value, account_investor1); + await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); + await I_CappedSTO_Array_ETH[0].reclaimERC20(I_PolyToken.address, { from: token_owner }); + assert.equal( + (await I_PolyToken.balanceOf(account_investor3)).toNumber(), + initInvestorBalance.toNumber(), + 'tokens are not transfered out from investor account' + ); + assert.equal( + (await I_PolyToken.balanceOf(token_owner)).toNumber(), + initOwnerBalance + .add(value) + .add(initContractBalance) + .toNumber(), + 'tokens are not added to the owner account' + ); + assert.equal( + (await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address)).toNumber(), + 0, + 'tokens are not trandfered out from STO contract' + ); + }); + }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); - I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); - }); + describe('Attach second ETH STO module', async () => { + it('Should successfully attach the second STO module to the security token', async () => { + startTime_ETH2 = latestTime() + duration.days(1); + endTime_ETH2 = startTime_ETH2 + duration.days(30); - it("Should verify the configuration of the STO", async() => { - assert.equal( - await I_CappedSTO_Array_ETH[1].startTime.call(), - startTime_ETH2, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[1].endTime.call(), - endTime_ETH2, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_ETH[1].cap.call()).toNumber(), - cap, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[1].rate.call(), - rate, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[1].fundRaiseTypes.call(E_fundRaiseType), - true, - "STO Configuration doesn't set as expected" - ); - }); + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner }); + let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH2, endTime_ETH2, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - it("Should successfully whitelist investor 3", async() => { + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); + I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); + }); - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + it('Should verify the configuration of the STO', async () => { + assert.equal(await I_CappedSTO_Array_ETH[1].startTime.call(), startTime_ETH2, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[1].endTime.call(), endTime_ETH2, "STO Configuration doesn't set as expected"); + assert.equal((await I_CappedSTO_Array_ETH[1].cap.call()).toNumber(), cap, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[1].rate.call(), rate, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[1].fundRaiseTypes.call(E_fundRaiseType), true, "STO Configuration doesn't set as expected"); + }); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); + it('Should successfully whitelist investor 3', async () => { + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - assert.equal(tx.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 500000 + }); - // Jump time to beyond STO start - await increaseTime(duration.days(2)); - }); + assert.equal(tx.logs[0].args._investor, account_investor3, 'Failed in adding the investor in whitelist'); - it("Should invest in second STO - fails due to incorrect beneficiary", async() => { + // Jump time to beyond STO start + await increaseTime(duration.days(2)); + }); - // Buying on behalf of another user should fail - - await catchRevert(I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') })); + it('Should invest in second STO - fails due to incorrect beneficiary', async () => { + // Buying on behalf of another user should fail - }); + await catchRevert( + I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from: account_issuer, value: web3.utils.toWei('1', 'ether') }) + ); + }); - it("Should allow non-matching beneficiary", async() => { - await I_CappedSTO_Array_ETH[1].changeAllowBeneficialInvestments(true, {from: account_issuer}); - let allow = await I_CappedSTO_Array_ETH[1].allowBeneficialInvestments(); - assert.equal(allow, true, "allowBeneficialInvestments should be true"); - }); + it('Should allow non-matching beneficiary', async () => { + await I_CappedSTO_Array_ETH[1].changeAllowBeneficialInvestments(true, { from: account_issuer }); + let allow = await I_CappedSTO_Array_ETH[1].allowBeneficialInvestments(); + assert.equal(allow, true, 'allowBeneficialInvestments should be true'); + }); - it("Should invest in second STO", async() => { + it('Should invest in second STO', async () => { + await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from: account_issuer, value: web3.utils.toWei('1', 'ether') }); - await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') }); + assert.equal((await I_CappedSTO_Array_ETH[1].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - assert.equal( - (await I_CappedSTO_Array_ETH[1].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); + assert.equal(await I_CappedSTO_Array_ETH[1].investorCount.call(), 1); - assert.equal(await I_CappedSTO_Array_ETH[1].investorCount.call(), 1); + assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor3)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); + }); + + describe('Test cases for reaching limit number of STO modules', async () => { + it('Should successfully attach 10 STO modules', async () => { + const MAX_MODULES = 10; + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + + await I_PolyToken.getTokens(cappedSTOSetupCost * 19, token_owner); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost * 19, { from: token_owner }); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + + for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', `Wrong STO module added at index ${STOIndex}`); + I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); + } + }); - assert.equal( - (await I_SecurityToken_ETH.balanceOf(account_investor3)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }); + it('Should successfully invest in all STO modules attached', async () => { + const MAX_MODULES = 10; + await increaseTime(duration.days(2)); + for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { + await I_CappedSTO_Array_ETH[STOIndex].buyTokens(account_investor3, { + from: account_investor3, + value: web3.utils.toWei('1', 'ether') + }); + assert.equal((await I_CappedSTO_Array_ETH[STOIndex].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); + assert.equal(await I_CappedSTO_Array_ETH[STOIndex].investorCount.call(), 1); + } + }); + }); + + describe('Test Cases for an STO of fundraise type POLY', async () => { + describe('Launch a new SecurityToken', async () => { + it('POLY: Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, P_symbol, P_name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, P_symbol); + }); + + it('POLY: Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, P_symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken_POLY = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken_POLY.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); + }); + + it('POLY: Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken_POLY.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it('POLY: Should successfully attach the STO module to the security token', async () => { + startTime_POLY1 = latestTime() + duration.days(2); + endTime_POLY1 = startTime_POLY1 + duration.days(30); + + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner }); + + let bytesSTO = encodeModuleCall(STOParameters, [ + startTime_POLY1, + endTime_POLY1, + P_cap, + P_rate, + [P_fundRaiseType], + account_fundsReceiver + ]); + + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); + I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); + }); }); - describe("Test cases for reaching limit number of STO modules", async() => { + describe('verify the data of STO', async () => { + it('Should verify the configuration of the STO', async () => { + assert.equal( + (await I_CappedSTO_Array_POLY[0].startTime.call()).toNumber(), + startTime_POLY1, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_POLY[0].endTime.call()).toNumber(), + endTime_POLY1, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_POLY[0].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), + BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), + "STO Configuration doesn't set as expected" + ); + assert.equal(await I_CappedSTO_Array_POLY[0].rate.call(), P_rate, "STO Configuration doesn't set as expected"); + assert.equal( + await I_CappedSTO_Array_POLY[0].fundRaiseTypes.call(P_fundRaiseType), + true, + "STO Configuration doesn't set as expected" + ); + }); + }); - it("Should successfully attach 10 STO modules", async () => { - const MAX_MODULES = 10; - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); + describe('Buy tokens', async () => { + it('Should Buy the tokens', async () => { + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_investor1); + blockNo = latestBlock(); + assert.equal( + (await I_PolyToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 10000, + 'Tokens are not transfered properly' + ); - await I_PolyToken.getTokens(cappedSTOSetupCost*19, token_owner); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost*19, { from: token_owner}); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, P_fromTime, P_toTime, P_expiryTime, true, { + from: account_issuer, + gas: 500000 + }); - for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); - I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); - } + assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); - }); + // Jump time + await increaseTime(duration.days(17)); + + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 }); - it("Should successfully invest in all STO modules attached", async () => { - const MAX_MODULES = 10; - await increaseTime(duration.days(2)); - for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { - await I_CappedSTO_Array_ETH[STOIndex].buyTokens(account_investor3, { from : account_investor3, value: web3.utils.toWei('1', 'ether') }); - assert.equal( - (await I_CappedSTO_Array_ETH[STOIndex].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); - assert.equal(await I_CappedSTO_Array_ETH[STOIndex].investorCount.call(), 1); - } + // buyTokensWithPoly transaction + await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { + from: account_investor1, + gas: 6000000 }); - }); - describe("Test Cases for an STO of fundraise type POLY", async() => { + assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - describe("Launch a new SecurityToken", async() => { + assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 1); - it("POLY: Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, P_symbol, P_name, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, P_symbol); - }); + assert.equal((await I_SecurityToken_POLY.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 5000); + }); - it("POLY: Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, { from: token_owner }); + it('Verification of the event Token Purchase', async () => { + const log = await promisifyLogWatch(I_CappedSTO_Array_POLY[0].TokenPurchase({ from: blockNo }), 1); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, P_symbol, "SecurityToken doesn't get deployed"); + assert.equal(log.args.purchaser, account_investor1, 'Wrong address of the investor'); + assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 5000, 'Wrong No. token get dilivered'); + }); - I_SecurityToken_POLY = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + it('Should restrict to buy tokens after hiting the cap in second tx first tx pass', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + P_fromTime, + P_toTime + duration.days(20), + P_expiryTime, + true, + { + from: account_issuer, + gas: 500000 + } + ); - const log = await promisifyLogWatch(I_SecurityToken_POLY.ModuleAdded({from: _blockNo}), 1); + assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); - }); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_investor2); - it("POLY: Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken_POLY.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 9000 * Math.pow(10, 18), { from: account_investor2 }); - it("POLY: Should successfully attach the STO module to the security token", async () => { - startTime_POLY1 = latestTime() + duration.days(2); - endTime_POLY1 = startTime_POLY1 + duration.days(30); + // buyTokensWithPoly transaction + await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(9000 * Math.pow(10, 18), { from: account_investor2, gas: 6000000 }); - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner}); + assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10000); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY1, endTime_POLY1, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); + assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + assert.equal((await I_SecurityToken_POLY.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 45000); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); - I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); - }); + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 })); + }); - }); + it('Should failed at the time of buying the tokens -- Because STO get expired', async () => { + await increaseTime(duration.days(31)); // increased beyond the end time of the STO - describe("verify the data of STO", async () => { - - it("Should verify the configuration of the STO", async() => { - assert.equal( - (await I_CappedSTO_Array_POLY[0].startTime.call()).toNumber(), - startTime_POLY1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_POLY[0].endTime.call()).toNumber(), - endTime_POLY1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_POLY[0].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), - BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_POLY[0].rate.call(), - P_rate, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_POLY[0].fundRaiseTypes.call(P_fundRaiseType), - true, - "STO Configuration doesn't set as expected" - ); - }); - }); + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 })); + }); - describe("Buy tokens", async() => { - - it("Should Buy the tokens", async() => { - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_investor1); - blockNo = latestBlock(); - assert.equal( - (await I_PolyToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 10000, - "Tokens are not transfered properly" - ); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - P_fromTime, - P_toTime, - P_expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(duration.days(17)); - - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}); - - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (1000 * Math.pow(10, 18)), - { - from : account_investor1, - gas: 6000000 - } - ); - - assert.equal( - (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - - assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 1); - - assert.equal( - (await I_SecurityToken_POLY.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 5000 - ); - }); - - it("Verification of the event Token Purchase", async() => { - const log = await promisifyLogWatch(I_CappedSTO_Array_POLY[0].TokenPurchase({from: blockNo}), 1); - - assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); - assert.equal( - (log.args.amount) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 5000, - "Wrong No. token get dilivered" - ); - }); - - it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - P_fromTime, - P_toTime + duration.days(20), - P_expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_investor2); - - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (9000 * Math.pow(10, 18)), { from: account_investor2}); - - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (9000 * Math.pow(10, 18)), - {from : account_investor2, gas: 6000000 } - ); - - assert.equal( - (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 10000 - ); - - assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); - - assert.equal( - (await I_SecurityToken_POLY.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 45000 - ); - - await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); - }); - - it("Should failed at the time of buying the tokens -- Because STO get expired", async() => { - await increaseTime(duration.days(31)); // increased beyond the end time of the STO - - await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); - }); - - it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { - const balanceRaised = await I_PolyToken.balanceOf.call(account_fundsReceiver); - assert.equal( - (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), - balanceRaised, - "Somewhere raised money get stolen or sent to wrong wallet" - ); - }); - - }); - - describe("Test cases for the CappedSTOFactory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal((await I_CappedSTOFactory.setupCost.call()).toNumber(), cappedSTOSetupCost); - assert.equal(await I_CappedSTOFactory.getType.call(),3); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), - "CappedSTO", - "Wrong Module added"); - assert.equal(await I_CappedSTOFactory.getDescription.call(), - "Use to collects the funds and once the cap is reached then investment will be no longer entertained", - "Wrong Module added"); - assert.equal(await I_CappedSTOFactory.getTitle.call(), - "Capped STO", - "Wrong Module added"); - assert.equal(await I_CappedSTOFactory.getInstructions.call(), - "Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)", - "Wrong Module added"); - let tags = await I_CappedSTOFactory.getTags.call(); - assert.equal(web3.utils.hexToString(tags[0]),"Capped"); - - }); - - it("Should fail to change the title -- bad owner", async() => { - - await catchRevert(I_CappedSTOFactory.changeTitle("STO Capped", {from:account_investor1})); - }); - - it("Should fail to change the title -- zero length", async() => { - - await catchRevert(I_CappedSTOFactory.changeTitle("", {from: token_owner})); - }); - - it("Should successfully change the title", async() => { - await I_CappedSTOFactory.changeTitle("STO Capped", {from: token_owner}); - assert.equal(await I_CappedSTOFactory.getTitle.call(), - "STO Capped", - "Title doesn't get changed"); - }); - - it("Should fail to change the description -- bad owner", async() => { - - await catchRevert(I_CappedSTOFactory.changeDescription("It is only a STO", {from:account_investor1})); - }); - - it("Should fail to change the description -- zero length", async() => { - - await catchRevert(I_CappedSTOFactory.changeDescription("", {from: token_owner})); - }); - - it("Should successfully change the description", async() => { - await I_CappedSTOFactory.changeDescription("It is only a STO", {from: token_owner}); - assert.equal(await I_CappedSTOFactory.getDescription.call(), - "It is only a STO", - "Description doesn't get changed"); - }); - - it("Should fail to change the name -- bad owner", async() => { - - await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from:account_investor1})); - }); - - it("Should fail to change the name -- zero length", async() => { - - await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(""), {from: token_owner})); - }); - - it("Should successfully change the name", async() => { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from: token_owner}); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), - "STOCapped", - "Name doesn't get changed"); - }); - - it("Should successfully change the name", async() => { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex("CappedSTO"), {from: token_owner}); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), - "CappedSTO", - "Name doesn't get changed"); - }); - - }); - - describe("Test cases for the get functions of the capped sto", async() => { - it("Should verify the cap reached or not", async() => { - assert.isTrue(await I_CappedSTO_Array_POLY[0].capReached.call()); - }); - - it("Should get the raised amount of ether", async() => { - assert.equal(await I_CappedSTO_Array_POLY[0].getRaised.call(ETH), web3.utils.toWei('0','ether')); - }); - - it("Should get the raised amount of poly", async() => { - assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('10000','ether')); - }); - - it("Should get the investors", async() => { - assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(),2); - }); - - it("Should get the listed permissions", async() => { - let tx = await I_CappedSTO_Array_POLY[0].getPermissions.call(); - assert.equal(tx.length,0); - }); - - it("Should get the metrics of the STO", async() => { - let metrics = await I_CappedSTO_Array_POLY[0].getSTODetails.call(); - assert.isTrue(metrics[7]); - }); - - }); + it('Should fundRaised value equal to the raised value in the funds receiver wallet', async () => { + const balanceRaised = await I_PolyToken.balanceOf.call(account_fundsReceiver); + assert.equal( + (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), + balanceRaised, + 'Somewhere raised money get stolen or sent to wrong wallet' + ); + }); }); - describe("Attach second POLY STO module", async() => { - it("Should successfully attach a second STO to the security token", async () => { - startTime_POLY2 = latestTime() + duration.days(1); - endTime_POLY2 = startTime_POLY2 + duration.days(30); + describe('Test cases for the CappedSTOFactory', async () => { + it('should get the exact details of the factory', async () => { + assert.equal((await I_CappedSTOFactory.setupCost.call()).toNumber(), cappedSTOSetupCost); + assert.equal(await I_CappedSTOFactory.getType.call(), 3); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), 'CappedSTO', 'Wrong Module added'); + assert.equal( + await I_CappedSTOFactory.getDescription.call(), + 'Use to collects the funds and once the cap is reached then investment will be no longer entertained', + 'Wrong Module added' + ); + assert.equal(await I_CappedSTOFactory.getTitle.call(), 'Capped STO', 'Wrong Module added'); + assert.equal( + await I_CappedSTOFactory.getInstructions.call(), + 'Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)', + 'Wrong Module added' + ); + let tags = await I_CappedSTOFactory.getTags.call(); + assert.equal(web3.utils.hexToString(tags[0]), 'Capped'); + }); + + it('Should fail to change the title -- bad owner', async () => { + await catchRevert(I_CappedSTOFactory.changeTitle('STO Capped', { from: account_investor1 })); + }); + + it('Should fail to change the title -- zero length', async () => { + await catchRevert(I_CappedSTOFactory.changeTitle('', { from: token_owner })); + }); + + it('Should successfully change the title', async () => { + await I_CappedSTOFactory.changeTitle('STO Capped', { from: token_owner }); + assert.equal(await I_CappedSTOFactory.getTitle.call(), 'STO Capped', "Title doesn't get changed"); + }); + + it('Should fail to change the description -- bad owner', async () => { + await catchRevert(I_CappedSTOFactory.changeDescription('It is only a STO', { from: account_investor1 })); + }); + + it('Should fail to change the description -- zero length', async () => { + await catchRevert(I_CappedSTOFactory.changeDescription('', { from: token_owner })); + }); + + it('Should successfully change the description', async () => { + await I_CappedSTOFactory.changeDescription('It is only a STO', { from: token_owner }); + assert.equal(await I_CappedSTOFactory.getDescription.call(), 'It is only a STO', "Description doesn't get changed"); + }); + + it('Should fail to change the name -- bad owner', async () => { + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex('STOCapped'), { from: account_investor1 })); + }); + + it('Should fail to change the name -- zero length', async () => { + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(''), { from: token_owner })); + }); + + it('Should successfully change the name', async () => { + await I_CappedSTOFactory.changeName(web3.utils.stringToHex('STOCapped'), { from: token_owner }); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), 'STOCapped', "Name doesn't get changed"); + }); + + it('Should successfully change the name', async () => { + await I_CappedSTOFactory.changeName(web3.utils.stringToHex('CappedSTO'), { from: token_owner }); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), 'CappedSTO', "Name doesn't get changed"); + }); + }); - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner}); + describe('Test cases for the get functions of the capped sto', async () => { + it('Should verify the cap reached or not', async () => { + assert.isTrue(await I_CappedSTO_Array_POLY[0].capReached.call()); + }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY2, endTime_POLY2, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); + it('Should get the raised amount of ether', async () => { + assert.equal(await I_CappedSTO_Array_POLY[0].getRaised.call(ETH), web3.utils.toWei('0', 'ether')); + }); - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + it('Should get the raised amount of poly', async () => { + assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('10000', 'ether')); + }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); - I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); - }); + it('Should get the investors', async () => { + assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); + }); - it("Should verify the configuration of the STO", async() => { - assert.equal( - (await I_CappedSTO_Array_POLY[1].startTime.call()).toNumber(), - startTime_POLY2, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_POLY[1].endTime.call()).toNumber(), - endTime_POLY2, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_POLY[1].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), - BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_POLY[1].rate.call(), - P_rate, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_POLY[1].fundRaiseTypes.call(P_fundRaiseType), - true, - "STO Configuration doesn't set as expected" - ); - }); + it('Should get the listed permissions', async () => { + let tx = await I_CappedSTO_Array_POLY[0].getPermissions.call(); + assert.equal(tx.length, 0); + }); - it("Should successfully invest in second STO", async() => { - - const polyToInvest = 1000; - const stToReceive = polyToInvest * P_rate; - - await I_PolyToken.getTokens((polyToInvest * Math.pow(10, 18)), account_investor3); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - P_fromTime, - P_toTime, - P_expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); - - // Jump time to beyond STO start - await increaseTime(duration.days(2)); - - await I_PolyToken.approve(I_CappedSTO_Array_POLY[1].address, (polyToInvest * Math.pow(10, 18)), { from: account_investor3 }); - - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[1].buyTokensWithPoly( - (polyToInvest * Math.pow(10, 18)), - { - from : account_investor3, - gas: 6000000 - } - ); - - assert.equal( - (await I_CappedSTO_Array_POLY[1].getRaised.call(POLY)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - polyToInvest - ); - - assert.equal(await I_CappedSTO_Array_POLY[1].investorCount.call(), 1); - - assert.equal( - (await I_SecurityToken_POLY.balanceOf(account_investor3)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - stToReceive - ); - }); + it('Should get the metrics of the STO', async () => { + let metrics = await I_CappedSTO_Array_POLY[0].getSTODetails.call(); + assert.isTrue(metrics[7]); + }); + }); + }); + + describe('Attach second POLY STO module', async () => { + it('Should successfully attach a second STO to the security token', async () => { + startTime_POLY2 = latestTime() + duration.days(1); + endTime_POLY2 = startTime_POLY2 + duration.days(30); + + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner }); + + let bytesSTO = encodeModuleCall(STOParameters, [ + startTime_POLY2, + endTime_POLY2, + P_cap, + P_rate, + [P_fundRaiseType], + account_fundsReceiver + ]); + + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); + I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); + }); + + it('Should verify the configuration of the STO', async () => { + assert.equal( + (await I_CappedSTO_Array_POLY[1].startTime.call()).toNumber(), + startTime_POLY2, + "STO Configuration doesn't set as expected" + ); + assert.equal((await I_CappedSTO_Array_POLY[1].endTime.call()).toNumber(), endTime_POLY2, "STO Configuration doesn't set as expected"); + assert.equal( + (await I_CappedSTO_Array_POLY[1].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), + BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), + "STO Configuration doesn't set as expected" + ); + assert.equal(await I_CappedSTO_Array_POLY[1].rate.call(), P_rate, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_POLY[1].fundRaiseTypes.call(P_fundRaiseType), true, "STO Configuration doesn't set as expected"); + }); + + it('Should successfully invest in second STO', async () => { + const polyToInvest = 1000; + const stToReceive = polyToInvest * P_rate; + + await I_PolyToken.getTokens(polyToInvest * Math.pow(10, 18), account_investor3); + + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, P_fromTime, P_toTime, P_expiryTime, true, { + from: account_issuer, + gas: 500000 + }); + + // Jump time to beyond STO start + await increaseTime(duration.days(2)); + + await I_PolyToken.approve(I_CappedSTO_Array_POLY[1].address, polyToInvest * Math.pow(10, 18), { from: account_investor3 }); + + // buyTokensWithPoly transaction + await I_CappedSTO_Array_POLY[1].buyTokensWithPoly(polyToInvest * Math.pow(10, 18), { + from: account_investor3, + gas: 6000000 + }); + + assert.equal((await I_CappedSTO_Array_POLY[1].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), polyToInvest); + + assert.equal(await I_CappedSTO_Array_POLY[1].investorCount.call(), 1); + + assert.equal((await I_SecurityToken_POLY.balanceOf(account_investor3)).dividedBy(new BigNumber(10).pow(18)).toNumber(), stToReceive); }); + }); }); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index 9714e7602..26ff736f4 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -8,83 +8,92 @@ const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('Checkpoints', accounts => { - - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_STRProxied; - let I_MRProxied; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - - // Step 1: Deploy the genral PM ecosystem - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_STRProxied; + let I_MRProxied; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -97,215 +106,205 @@ contract('Checkpoints', accounts => { GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - describe("Generate the SecurityToken", async() => { + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + }); + + describe('Buy tokens using on-chain whitelist', async () => { + it('Should Buy the tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + false, + { + from: account_issuer, + gas: 6000000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('10', 'ether')); + }); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); + it('Should Buy some more tokens', async () => { + // Add the Investor in to the whitelist - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + false, + { + from: account_issuer, + gas: 6000000 + } + ); + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('10', 'ether')); }); - describe("Buy tokens using on-chain whitelist", async() => { - - it("Should Buy the tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - false, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('10', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('10', 'ether') - ); - }); - - it("Should Buy some more tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - false, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('10', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('10', 'ether') - ); - }); - - it("Add a new token holder", async() => { - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - false, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('10', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('10', 'ether') - ); - }); - - it("Fuzz test balance checkpoints", async() => { - await I_SecurityToken.changeGranularity(1, {from: token_owner}); - let cps = []; - let ts = []; - for (let j = 0; j < 10; j++) { - let balance1 = BigNumber(await I_SecurityToken.balanceOf(account_investor1)); - let balance2 = BigNumber(await I_SecurityToken.balanceOf(account_investor2)); - let balance3 = BigNumber(await I_SecurityToken.balanceOf(account_investor3)); - let totalSupply = BigNumber(await I_SecurityToken.totalSupply()); - cps.push([balance1, balance2, balance3]); - ts.push(totalSupply); - console.log("Checkpoint: " + (j + 1) + " Balances: " + JSON.stringify(cps[cps.length - 1]) + " TotalSupply: " + JSON.stringify(totalSupply)); - await I_SecurityToken.createCheckpoint({ from: token_owner }); - let checkpointTimes = (await I_SecurityToken.getCheckpointTimes()); - assert.equal(checkpointTimes.length, (j + 1)); - console.log("Checkpoint Times: " + checkpointTimes); - let txs = Math.floor(Math.random() * 3); - for (let i = 0; i < txs; i++) { - let sender; - let receiver; - let s = Math.random() * 3; - if (s < 1) { - sender = account_investor1; - } else if (s < 2) { - sender = account_investor2; - } else { - sender = account_investor3; - } - let r = Math.random() * 3; - if (r < 1) { - receiver = account_investor1; - } else if (r < 2) { - receiver = account_investor2; - } else { - receiver = account_investor3; - } - let m = Math.random(); - let amount = BigNumber(await I_SecurityToken.balanceOf(sender)).mul(Math.random().toFixed(10)).toFixed(0); - if (m > 0.8) { - console.log("Sending full balance"); - amount = BigNumber(await I_SecurityToken.balanceOf(sender)); - } - console.log("Sender: " + sender + " Receiver: " + receiver + " Amount: " + JSON.stringify(amount)); - await I_SecurityToken.transfer(receiver, amount, { from: sender }); - } - if (Math.random() > 0.5) { - let n = BigNumber(Math.random().toFixed(10)).mul(10**17).toFixed(0); - let p = Math.random() * 3; - let r = Math.random() * 3; - let minter; - if (r < 1) { - minter = account_investor1; - } else if (r < 2) { - minter = account_investor2; - } else { - minter = account_investor3; - } - console.log("Minting: " + n.toString() + " to: " + minter); - await I_SecurityToken.mint(minter, n, { from: token_owner }); - } - console.log("Checking Interim..."); - for (let k = 0; k < cps.length; k++) { - let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); - let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); - let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); - let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); - let balances = [balance1, balance2, balance3]; - console.log("Checking TotalSupply: " + totalSupply + " is " + ts[k] + " at checkpoint: " + (k + 1)); - assert.isTrue(totalSupply.eq(ts[k])); - console.log("Checking Balances: " + balances + " is " + cps[k] + " at checkpoint: " + (k + 1)); - for (let l = 0; l < cps[k].length; l++) { - // console.log(balances[l].toString(), cps[k][l].toString()); - assert.isTrue(balances[l].eq(cps[k][l])); - } - } - } - console.log("Checking..."); - for (let k = 0; k < cps.length; k++) { - let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); - let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); - let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); - let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); - let balances = [balance1, balance2, balance3]; - console.log("Checking TotalSupply: " + totalSupply + " is " + ts[k] + " at checkpoint: " + (k + 1)); - assert.isTrue(totalSupply.eq(ts[k])); - console.log("Checking Balances: " + balances + " is " + cps[k] + " at checkpoint: " + (k + 1)); - for (let l = 0; l < cps[k].length; l++) { - // console.log(balances[l].toString(), cps[k][l].toString()); - assert.isTrue(balances[l].eq(cps[k][l])); - } - } - - }); + it('Add a new token holder', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + false, + { + from: account_issuer, + gas: 6000000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('10', 'ether')); }); + it('Fuzz test balance checkpoints', async () => { + await I_SecurityToken.changeGranularity(1, { from: token_owner }); + let cps = []; + let ts = []; + for (let j = 0; j < 10; j++) { + let balance1 = BigNumber(await I_SecurityToken.balanceOf(account_investor1)); + let balance2 = BigNumber(await I_SecurityToken.balanceOf(account_investor2)); + let balance3 = BigNumber(await I_SecurityToken.balanceOf(account_investor3)); + let totalSupply = BigNumber(await I_SecurityToken.totalSupply()); + cps.push([balance1, balance2, balance3]); + ts.push(totalSupply); + console.log( + 'Checkpoint: ' + (j + 1) + ' Balances: ' + JSON.stringify(cps[cps.length - 1]) + ' TotalSupply: ' + JSON.stringify(totalSupply) + ); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + let checkpointTimes = await I_SecurityToken.getCheckpointTimes(); + assert.equal(checkpointTimes.length, j + 1); + console.log('Checkpoint Times: ' + checkpointTimes); + let txs = Math.floor(Math.random() * 3); + for (let i = 0; i < txs; i++) { + let sender; + let receiver; + let s = Math.random() * 3; + if (s < 1) { + sender = account_investor1; + } else if (s < 2) { + sender = account_investor2; + } else { + sender = account_investor3; + } + let r = Math.random() * 3; + if (r < 1) { + receiver = account_investor1; + } else if (r < 2) { + receiver = account_investor2; + } else { + receiver = account_investor3; + } + let m = Math.random(); + let amount = BigNumber(await I_SecurityToken.balanceOf(sender)) + .mul(Math.random().toFixed(10)) + .toFixed(0); + if (m > 0.8) { + console.log('Sending full balance'); + amount = BigNumber(await I_SecurityToken.balanceOf(sender)); + } + console.log('Sender: ' + sender + ' Receiver: ' + receiver + ' Amount: ' + JSON.stringify(amount)); + await I_SecurityToken.transfer(receiver, amount, { from: sender }); + } + if (Math.random() > 0.5) { + let n = BigNumber(Math.random().toFixed(10)) + .mul(10 ** 17) + .toFixed(0); + let p = Math.random() * 3; + let r = Math.random() * 3; + let minter; + if (r < 1) { + minter = account_investor1; + } else if (r < 2) { + minter = account_investor2; + } else { + minter = account_investor3; + } + console.log('Minting: ' + n.toString() + ' to: ' + minter); + await I_SecurityToken.mint(minter, n, { from: token_owner }); + } + console.log('Checking Interim...'); + for (let k = 0; k < cps.length; k++) { + let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); + let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); + let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); + let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); + let balances = [balance1, balance2, balance3]; + console.log('Checking TotalSupply: ' + totalSupply + ' is ' + ts[k] + ' at checkpoint: ' + (k + 1)); + assert.isTrue(totalSupply.eq(ts[k])); + console.log('Checking Balances: ' + balances + ' is ' + cps[k] + ' at checkpoint: ' + (k + 1)); + for (let l = 0; l < cps[k].length; l++) { + // console.log(balances[l].toString(), cps[k][l].toString()); + assert.isTrue(balances[l].eq(cps[k][l])); + } + } + } + console.log('Checking...'); + for (let k = 0; k < cps.length; k++) { + let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); + let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); + let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); + let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); + let balances = [balance1, balance2, balance3]; + console.log('Checking TotalSupply: ' + totalSupply + ' is ' + ts[k] + ' at checkpoint: ' + (k + 1)); + assert.isTrue(totalSupply.eq(ts[k])); + console.log('Checking Balances: ' + balances + ' is ' + cps[k] + ' at checkpoint: ' + (k + 1)); + for (let l = 0; l < cps[k].length; l++) { + // console.log(balances[l].toString(), cps[k][l].toString()); + assert.isTrue(balances[l].eq(cps[k][l])); + } + } + }); + }); }); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index a4e7aa565..339cc9a0c 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -12,109 +12,121 @@ const CountTransferManager = artifacts.require('./CountTransferManager'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('CountTransferManager', accounts => { - - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_SecurityTokenRegistryProxy; - let P_CountTransferManagerFactory; - let P_CountTransferManager; - let I_GeneralTransferManagerFactory; - let I_CountTransferManagerFactory; - let I_GeneralPermissionManager; - let I_CountTransferManager; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_MRProxied; - let I_STRProxied; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // CountTransferManager details - const holderCount = 2; // Maximum number of token holders - let bytesSTO = encodeModuleCall(['uint256'], [holderCount]); - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[7]; - account_investor2 = accounts[8]; - account_investor3 = accounts[9]; - - // Step 1: Deploy the genral PM ecosystem - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - - // STEP 2: Deploy the CountTransferManager - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_CountTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CountTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy Paid the CountTransferManager - P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); - assert.notEqual( - P_CountTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CountTransferManagerFactory contract was not deployed" - ); - - // (C) : Register the CountTransferManagerFactory - await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid CountTransferManagerFactory - await I_MRProxied.registerModule(P_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_CountTransferManagerFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + + // Contract Instance Declaration + let I_SecurityTokenRegistryProxy; + let P_CountTransferManagerFactory; + let P_CountTransferManager; + let I_GeneralTransferManagerFactory; + let I_CountTransferManagerFactory; + let I_GeneralPermissionManager; + let I_CountTransferManager; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_MRProxied; + let I_STRProxied; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // CountTransferManager details + const holderCount = 2; // Maximum number of token holders + let bytesSTO = encodeModuleCall(['uint256'], [holderCount]); + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[7]; + account_investor2 = accounts[8]; + account_investor3 = accounts[9]; + + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 2: Deploy the CountTransferManager + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_CountTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CountTransferManagerFactory contract was not deployed' + ); + + // STEP 3: Deploy Paid the CountTransferManager + P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei('500', 'ether'), 0, 0, { + from: account_polymath + }); + assert.notEqual( + P_CountTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CountTransferManagerFactory contract was not deployed' + ); + + // (C) : Register the CountTransferManagerFactory + await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the Paid CountTransferManagerFactory + await I_MRProxied.registerModule(P_CountTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_CountTransferManagerFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -128,243 +140,215 @@ contract('CountTransferManager', accounts => { CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - it("Should successfully attach the CountTransferManager factory with the security token", async () => { - - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); - }); - - it("Should successfully attach the CountTransferManager factory with the security token", async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "CountTransferManager", - "CountTransferManagerFactory module was not added" - ); - P_CountTransferManager = CountTransferManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it("Should successfully attach the CountTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "CountTransferManager", - "CountTransferManager module was not added" - ); - I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); - }); + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); }); - describe("Buy tokens using on-chain whitelist", async() => { - - it("Should Buy the tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should Buy some more tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Should fail to buy some more tokens (more than 2 holders)", async() => { - // Add the Investor in to the whitelist - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); - - - await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner })); - }); - - - it("Should still be able to add to original token holders", async() => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('4', 'ether') - ); - }); - - it("Should still be able to transfer between existing token holders before count change", async() => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Should fail in modifying the holder count", async() => { - - await catchRevert(I_CountTransferManager.changeHolderCount(1, { from: account_investor1 })); + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it('Should successfully attach the CountTransferManager factory with the security token', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); + await catchRevert( + I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei('500', 'ether'), 0, { + from: token_owner }) + ); + }); + + it('Should successfully attach the CountTransferManager factory with the security token', async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei('500', 'ether'), 0, { + from: token_owner + }); + assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), + 'CountTransferManager', + 'CountTransferManagerFactory module was not added' + ); + P_CountTransferManager = CountTransferManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it('Should successfully attach the CountTransferManager with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'CountTransferManager', + 'CountTransferManager module was not added' + ); + I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); + }); + }); + + describe('Buy tokens using on-chain whitelist', async () => { + it('Should Buy the tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Should Buy some more tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + } + ); - it("Modify holder count to 1", async() => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_CountTransferManager.changeHolderCount(1, { from: token_owner }); - - assert.equal( - (await I_CountTransferManager.maxHolderCount()).toNumber(), - 1 - ); - }); - - it("Should still be able to transfer between existing token holders after count change", async() => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('4', 'ether') - ); - }); - - it("Should not be able to transfer to a new token holder", async() => { - - // await I_CountTransferManager.unpause({from: token_owner}); - await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 })); - - }); - - it("Should be able to consolidate balances", async() => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - }); - - it("Should get the permission list", async() => { - let perm = await I_CountTransferManager.getPermissions.call(); - assert.equal(perm.length, 1); - }); - - describe("Test cases for the factory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_CountTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_CountTransferManagerFactory.getType.call(),2); - assert.equal(web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "CountTransferManager", - "Wrong Module added"); - assert.equal(await I_CountTransferManagerFactory.getDescription.call(), - "Restrict the number of investors", - "Wrong Module added"); - assert.equal(await I_CountTransferManagerFactory.getTitle.call(), - "Count Transfer Manager", - "Wrong Module added"); - assert.equal(await I_CountTransferManagerFactory.getInstructions.call(), - "Allows an issuer to restrict the total number of non-zero token holders", - "Wrong Module added"); - - }); - - it("Should get the tags of the factory", async() => { - let tags = await I_CountTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''),"Count"); - }); - }); + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + + it('Should fail to buy some more tokens (more than 2 holders)', async () => { + // Add the Investor in to the whitelist + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); + + await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner })); + }); + + it('Should still be able to add to original token holders', async () => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('4', 'ether')); + }); + + it('Should still be able to transfer between existing token holders before count change', async () => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + + it('Should fail in modifying the holder count', async () => { + await catchRevert(I_CountTransferManager.changeHolderCount(1, { from: account_investor1 })); + }); + + it('Modify holder count to 1', async () => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_CountTransferManager.changeHolderCount(1, { from: token_owner }); + + assert.equal((await I_CountTransferManager.maxHolderCount()).toNumber(), 1); }); + it('Should still be able to transfer between existing token holders after count change', async () => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('4', 'ether')); + }); + + it('Should not be able to transfer to a new token holder', async () => { + // await I_CountTransferManager.unpause({from: token_owner}); + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 })); + }); + + it('Should be able to consolidate balances', async () => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + }); + + it('Should get the permission list', async () => { + let perm = await I_CountTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + }); + + describe('Test cases for the factory', async () => { + it('should get the exact details of the factory', async () => { + assert.equal(await I_CountTransferManagerFactory.setupCost.call(), 0); + assert.equal(await I_CountTransferManagerFactory.getType.call(), 2); + assert.equal( + web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()).replace(/\u0000/g, ''), + 'CountTransferManager', + 'Wrong Module added' + ); + assert.equal(await I_CountTransferManagerFactory.getDescription.call(), 'Restrict the number of investors', 'Wrong Module added'); + assert.equal(await I_CountTransferManagerFactory.getTitle.call(), 'Count Transfer Manager', 'Wrong Module added'); + assert.equal( + await I_CountTransferManagerFactory.getInstructions.call(), + 'Allows an issuer to restrict the total number of non-zero token holders', + 'Wrong Module added' + ); + }); + + it('Should get the tags of the factory', async () => { + let tags = await I_CountTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Count'); + }); + }); + }); }); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 366268e9e..2aed7cc68 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -11,112 +11,128 @@ const ERC20DividendCheckpoint = artifacts.require('./ERC20DividendCheckpoint'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('ERC20DividendCheckpoint', accounts => { - - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; - - // Contract Instance Declaration - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_ERC20DividendCheckpointFactory; - let P_ERC20DividendCheckpointFactory; - let P_ERC20DividendCheckpoint; - let I_GeneralPermissionManager; - let I_ERC20DividendCheckpoint; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_STRProxied; - let I_MRProxied; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - let snapId; - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - // Step 1: Deploy the genral PM ecosystem - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - - // STEP 6: Deploy the ERC20DividendCheckpoint - P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); - assert.notEqual( - P_ERC20DividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ERC20DividendCheckpointFactory contract was not deployed" - ); - - // STEP 7: Deploy the ERC20DividendCheckpoint - I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_ERC20DividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ERC20DividendCheckpointFactory contract was not deployed" - ); - - // STEP 8: Register the Modules with the ModuleRegistry contract - - // (A) : Register the ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - - // (B) : Register the Paid ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_temp; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + let dividendName = '0x546573744469766964656e640000000000000000000000000000000000000000'; + + // Contract Instance Declaration + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_ERC20DividendCheckpointFactory; + let P_ERC20DividendCheckpointFactory; + let P_ERC20DividendCheckpoint; + let I_GeneralPermissionManager; + let I_ERC20DividendCheckpoint; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_STRProxied; + let I_MRProxied; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + let snapId; + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const checkpointKey = 4; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; + + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 6: Deploy the ERC20DividendCheckpoint + P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new( + I_PolyToken.address, + web3.utils.toWei('500', 'ether'), + 0, + 0, + { from: account_polymath } + ); + assert.notEqual( + P_ERC20DividendCheckpointFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'ERC20DividendCheckpointFactory contract was not deployed' + ); + + // STEP 7: Deploy the ERC20DividendCheckpoint + I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_ERC20DividendCheckpointFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'ERC20DividendCheckpointFactory contract was not deployed' + ); + + // STEP 8: Register the Modules with the ModuleRegistry contract + + // (A) : Register the ERC20DividendCheckpointFactory + await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + + // (B) : Register the Paid ERC20DividendCheckpointFactory + await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -130,698 +146,767 @@ contract('ERC20DividendCheckpoint', accounts => { ERC20DividendCheckpointFactory: ${I_ERC20DividendCheckpointFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); + + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it('Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment', async () => { + await catchRevert( + I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { from: token_owner }), + 'tx -> failed because Token is not paid' + ); + }); + + it('Should successfully attach the ERC20DividendCheckpoint with the security token with budget', async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { + from: token_owner + }); + assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), + 'ERC20DividendCheckpoint', + 'ERC20DividendCheckpoint module was not added' + ); + P_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it('Should successfully attach the ERC20DividendCheckpoint with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, '', 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'ERC20DividendCheckpoint', + 'ERC20DividendCheckpoint module was not added' + ); + I_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[2].args._module); + }); + }); + + describe('Check Dividend payouts', async () => { + it('Buy some tokens for account_investor1 (1 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Buy some tokens for account_investor2 (2 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + + it('Should fail in creating the dividend - incorrect allowance', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, { + from: token_owner + }), + 'tx -> failed because allowance = 0' + ); + }); + + it('Should fail in creating the dividend - maturity > expiry', async () => { + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), { from: token_owner }); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, { + from: token_owner + }), + 'tx -> failed because maturity > expiry' + ); + }); + + it('Should fail in creating the dividend - now > expiry', async () => { + let maturity = latestTime() - duration.days(2); + let expiry = latestTime() - duration.days(1); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, { + from: token_owner + }), + 'tx -> failed because now > expiry' + ); + }); + + it('Should fail in creating the dividend - bad token', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, { + from: token_owner + }), + 'tx -> failed because token address is 0x' + ); + }); + + it('Should fail in creating the dividend - amount is 0', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, { from: token_owner }), + 'tx -> failed because amount < 0' + ); + }); + + it('Create new dividend of POLY tokens', async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + + let tx = await I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('1.5', 'ether'), + dividendName, + { from: token_owner } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, 'Dividend should be created at checkpoint 1'); + assert.equal(tx.logs[0].args._name.toString(), dividendName, 'Dividend name incorrect in event'); + }); + + it('Investor 1 transfers his token balance to investor 2', async () => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner }), + 'tx -> failed because dividend index has maturity in future' + ); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails not owner', async () => { + // Increase time by 2 day + await increaseTime(duration.days(2)); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: account_temp }), + 'tx -> failed because msg.sender is not the owner' + ); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }), + 'tx -> failed because dividend index is greator than the dividend array length' + ); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - it("Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment", async () => { - await catchRevert( - I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }), - "tx -> failed because Token is not paid" - ); - }); - - it("Should successfully attach the ERC20DividendCheckpoint with the security token with budget", async () => { - let snapId = await takeSnapshot() - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "ERC20DividendCheckpoint", - "ERC20DividendCheckpoint module was not added" - ); - P_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "ERC20DividendCheckpoint", - "ERC20DividendCheckpoint module was not added" - ); - I_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[2].args._module); - }); - }); - - describe("Check Dividend payouts", async() => { - - it("Buy some tokens for account_investor1 (1 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Buy some tokens for account_investor2 (2 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Should fail in creating the dividend - incorrect allowance", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because allowance = 0" - ); - }); - - it("Should fail in creating the dividend - maturity > expiry", async() => { - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because maturity > expiry" - ); - }); - - it("Should fail in creating the dividend - now > expiry", async() => { - let maturity = latestTime() - duration.days(2); - let expiry = latestTime() - duration.days(1); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because now > expiry" - ); - }); - - it("Should fail in creating the dividend - bad token", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because token address is 0x" - ); - }); - - it("Should fail in creating the dividend - amount is 0", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}), - "tx -> failed because amount < 0" - ); - }); - - it("Create new dividend of POLY tokens", async() => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); - assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); - }); - - it("Investor 1 transfers his token balance to investor 2", async() => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), {from: account_investor1}); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}), - "tx -> failed because dividend index has maturity in future" - ); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails not owner", async() => { - // Increase time by 2 day - await increaseTime(duration.days(2)); - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}), - "tx -> failed because msg.sender is not the owner" - ); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}), - "tx -> failed because dividend index is greator than the dividend array length" - ); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner, gas: 5000000}); - let investor1BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('1', 'ether')); - //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); - }); - - it("Buy some tokens for account_temp (1 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - latestTime(), - latestTime(), - latestTime() + duration.days(20), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_temp)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should not allow to create dividend without name", async() => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}), - "tx -> failed because dividend name is empty" - ); - }); - - it("Create new dividend", async() => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - // transfer approved in above test - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 1"); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry", async() => { - await increaseTime(duration.days(12)); - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}), - "tx -> failed because dividend index has passed its expiry" - ); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoin - fails already reclaimed", async() => { - let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); - assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}), - "tx -> failed because dividend index has already been reclaimed" - ); - }); - - it("Buy some tokens for account_investor3 (7 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('7', 'ether') - ); - }); - - it("Should allow to exclude same number of address as EXCLUDED_ADDRESS_LIMIT", async() => { - let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber() - 1; - let addresses = []; - addresses.push(account_temp); - while(limit--) - addresses.push(limit); - await I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}); - let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); - assert.equal(excluded[0], account_temp); - }); - - it("Exclude account_temp using global exclusion list", async() => { - await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], {from: token_owner}); - let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); - assert.equal(excluded[0], account_temp); - }); - - it("Should not allow to exclude more address than EXCLUDED_ADDRESS_LIMIT", async() => { - let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber(); - let addresses = []; - addresses.push(account_temp); - while(limit--) - addresses.push(limit); - await catchRevert( - I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}), - "tx -> failed because exclude address more than limit" - ); - }); - - it("Create another new dividend", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), dividendName, {from: token_owner}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 2"); - }); - - it("should investor 3 claims dividend - fail bad index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}), - "tx -> failed because dividend index is not valid" - ); - }); - - it("should investor 3 claims dividend", async() => { - console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it("should investor 3 claims dividend - fails already claimed", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}), - "tx -> failed because investor already claimed the dividend" - ); - }); - - it("should issuer pushes remain", async() => { - console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let investorTempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); - let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let investorTempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('3', 'ether')); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(investorTempBalanceAfter2.sub(investorTempBalanceAfter1).toNumber(), 0); - //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('10', 'ether')); - }); - - - it("Delete global exclusion list", async() => { - await I_ERC20DividendCheckpoint.setDefaultExcluded([], {from: token_owner}); - }); - - - it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); - }); - - it("Create another new dividend with explicit checkpoint - fails bad allowance", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); - console.log(JSON.stringify(tx.logs[0].args)); - console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), - "tx -> failed because allowance is not provided" - ); - }); - - it("Create another new dividend with explicit - fails maturity > expiry", async() => { - console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), {from: token_owner}); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), - "tx -> failed because maturity > expiry" - ); - }); - - it("Create another new dividend with explicit - fails now > expiry", async() => { - console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - - let maturity = latestTime() - duration.days(5); - let expiry = latestTime() - duration.days(2); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), - "tx -> failed because now > expiry" - ); - }); - - it("Create another new dividend with explicit - fails bad checkpoint", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}), - "tx -> failed because checkpoint id > current checkpoint" - ); - }); - - it("Set withholding tax of 20% on account_temp and 10% on investor2", async() => { - await I_ERC20DividendCheckpoint.setWithholding([account_temp, account_investor2], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}); - }); - - it("Should not allow mismatching input lengths", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}), - "tx -> failed because mismatching input lengths" - ); - }); - - it("Should not allow withholding greater than limit", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**26)], {from: token_owner}), - "tx -> failed because withholding greater than limit" - ); - await catchRevert( - I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20*10**26), {from: token_owner}), - "" - ); - }); - - it("Should not create dividend with more exclusions than limit", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); - let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber(); - let addresses = []; - addresses.push(account_temp); - while(limit--) - addresses.push(limit); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, addresses, dividendName, {from: token_owner}), - "tx -> failed because too many address excluded" - ); - }); - - it("Create another new dividend with explicit checkpoint and exclusion", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - //token transfer approved in above test - let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, [account_investor1], dividendName, {from: token_owner}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 3"); - }); - - it("Should not allow excluded to pull Dividend Payment", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor1, gasPrice: 0}), - "tx -> failed because msg.sender is excluded" - ); - }); - - it("Investor 2 claims dividend, issuer pushes investor 1 - fails not owner", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}), - "tx -> failed because not called by the owner" - ); - }); - - it("Investor 2 claims dividend, issuer pushes investor 1 - fails bad index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}), - "tx -> failed because dividend index is not valid" - ); - }); - - it("should not calculate dividend for invalid index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1), - "tx -> failed because dividend index is not valid" - ); - }); - - it("should calculate dividend before the push dividend payment", async() => { - let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); - let dividendAmount3 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor3); - let dividendAmount_temp = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_temp); - assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei("0", "ether")); - assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei("2", "ether")); - assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei("7", "ether")); - assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei("1", "ether")); - assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei("0", "ether")); - assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("0.2", "ether")); - assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei("0", "ether")); - assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0.2", "ether")); - }); - - it("Investor 2 claims dividend", async() => { - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); - await I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor2, gasPrice: 0}); - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.8', 'ether')); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); - assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); - }); - - it("Should issuer pushes temp investor - investor1 excluded", async() => { - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(3, [account_temp, account_investor1], {from: token_owner}); - let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('0.8', 'ether')); - //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); - }); - - it("should calculate dividend after the push dividend payment", async() => { - let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); - assert.equal(dividendAmount1[0].toNumber(), 0); - assert.equal(dividendAmount2[0].toNumber(), 0); - }); - - it("Should not allow reclaiming withholding tax with incorrect index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), - "tx -> failed because dividend index is not valid" - ); - }); - - it("Issuer reclaims withholding tax", async() => { - let issuerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); - await I_ERC20DividendCheckpoint.withdrawWithholding(3, {from: token_owner, gasPrice: 0}); - let issuerBalanceAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.4', 'ether')) - }); - - it("Issuer unable to reclaim dividend (expiry not passed)", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner}), - "tx -> failed because expiry is in the future" - ); - }); - - it("Issuer is unable to reclaim invalid dividend", async() => { - await increaseTime(11 * 24 * 60 * 60); - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}), - "tx -> failed because dividend index is not valid" - ); - }); - - it("Investor 3 unable to pull dividend after expiry", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), - "tx -> failed because expiry is in the past" - ); - }); - - it("Issuer is able to reclaim dividend after expiry", async() => { - let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); - await I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); - let tokenOwnerAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); - assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - - it("Issuer is unable to reclaim already reclaimed dividend", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}), - "tx -> failed because dividend are already reclaimed" - ); - }); - - it("Investor 3 unable to pull dividend after reclaiming", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), - "tx -> failed because expiry is in the past" - ); - }); - - it("Should give the right dividend index", async() => { - let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(3); - assert.equal(index[0], 2); - }); - - it("Should give the right dividend index", async() => { - let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(8); - assert.equal(index.length, 0); - }); - - it("Get the init data", async() => { - let tx = await I_ERC20DividendCheckpoint.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); - }); - - it("Should get the listed permissions", async() => { - let tx = await I_ERC20DividendCheckpoint.getPermissions.call(); - assert.equal(tx.length,1); - }); - - describe("Test cases for the ERC20DividendCheckpointFactory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(), 4); - assert.equal(await I_ERC20DividendCheckpointFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()) - .replace(/\u0000/g, ''), - "ERC20DividendCheckpoint", - "Wrong Module added"); - assert.equal(await I_ERC20DividendCheckpointFactory.getDescription.call(), - "Create ERC20 dividends for token holders at a specific checkpoint", - "Wrong Module added"); - assert.equal(await I_ERC20DividendCheckpointFactory.getTitle.call(), - "ERC20 Dividend Checkpoint", - "Wrong Module added"); - assert.equal(await I_ERC20DividendCheckpointFactory.getInstructions.call(), - "Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", - "Wrong Module added"); - let tags = await I_ERC20DividendCheckpointFactory.getTags.call(); - assert.equal(tags.length, 3); - - }); - }); + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner, gas: 5000000 }); + let investor1BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); + assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('1', 'ether')); + //Check fully claimed + assert.equal((await I_ERC20DividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); + }); + + it('Buy some tokens for account_temp (1 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_temp, + latestTime(), + latestTime(), + latestTime() + duration.days(20), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); + assert.equal((await I_SecurityToken.balanceOf(account_temp)).toNumber(), web3.utils.toWei('1', 'ether')); }); + it('Should not allow to create dividend without name', async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), { from: token_owner }); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', { + from: token_owner + }), + 'tx -> failed because dividend name is empty' + ); + }); + + it('Create new dividend', async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + // transfer approved in above test + let tx = await I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('1.5', 'ether'), + dividendName, + { from: token_owner } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, 'Dividend should be created at checkpoint 1'); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry', async () => { + await increaseTime(duration.days(12)); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, { from: token_owner }), + 'tx -> failed because dividend index has passed its expiry' + ); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoin - fails already reclaimed', async () => { + let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }); + assert.equal(tx.logs[0].args._claimedAmount.toNumber(), web3.utils.toWei('1.5', 'ether')); + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }), + 'tx -> failed because dividend index has already been reclaimed' + ); + }); + + it('Buy some tokens for account_investor3 (7 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it('Should allow to exclude same number of address as EXCLUDED_ADDRESS_LIMIT', async () => { + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber() - 1; + let addresses = []; + addresses.push(account_temp); + while (limit--) addresses.push(limit); + await I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, { from: token_owner }); + let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); + assert.equal(excluded[0], account_temp); + }); + + it('Exclude account_temp using global exclusion list', async () => { + await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], { from: token_owner }); + let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); + assert.equal(excluded[0], account_temp); + }); + + it('Should not allow to exclude more address than EXCLUDED_ADDRESS_LIMIT', async () => { + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while (limit--) addresses.push(limit); + await catchRevert( + I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, { from: token_owner }), + 'tx -> failed because exclude address more than limit' + ); + }); + + it('Create another new dividend', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), { from: token_owner }); + let tx = await I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('10', 'ether'), + dividendName, + { from: token_owner } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, 'Dividend should be created at checkpoint 2'); + }); + + it('should investor 3 claims dividend - fail bad index', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(5, { from: account_investor3, gasPrice: 0 }), + 'tx -> failed because dividend index is not valid' + ); + }); + + it('should investor 3 claims dividend', async () => { + console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await I_ERC20DividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }); + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it('should investor 3 claims dividend - fails already claimed', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }), + 'tx -> failed because investor already claimed the dividend' + ); + }); + + it('should issuer pushes remain', async () => { + console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let investorTempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); + let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let investorTempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('3', 'ether')); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + assert.equal(investorTempBalanceAfter2.sub(investorTempBalanceAfter1).toNumber(), 0); + //Check fully claimed + assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('10', 'ether')); + }); + + it('Delete global exclusion list', async () => { + await I_ERC20DividendCheckpoint.setDefaultExcluded([], { from: token_owner }); + }); + + it('Investor 2 transfers 1 ETH of his token balance to investor 1', async () => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); + }); + + it('Create another new dividend with explicit checkpoint - fails bad allowance', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + let tx = await I_SecurityToken.createCheckpoint({ from: token_owner }); + console.log(JSON.stringify(tx.logs[0].args)); + console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); + await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('20', 'ether'), + 4, + dividendName, + { from: token_owner } + ), + 'tx -> failed because allowance is not provided' + ); + }); + + it('Create another new dividend with explicit - fails maturity > expiry', async () => { + console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); + + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), { from: token_owner }); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('20', 'ether'), + 4, + dividendName, + { from: token_owner } + ), + 'tx -> failed because maturity > expiry' + ); + }); + + it('Create another new dividend with explicit - fails now > expiry', async () => { + console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); + + let maturity = latestTime() - duration.days(5); + let expiry = latestTime() - duration.days(2); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('20', 'ether'), + 4, + dividendName, + { from: token_owner } + ), + 'tx -> failed because now > expiry' + ); + }); + + it('Create another new dividend with explicit - fails bad checkpoint', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('20', 'ether'), + 5, + dividendName, + { from: token_owner } + ), + 'tx -> failed because checkpoint id > current checkpoint' + ); + }); + + it('Set withholding tax of 20% on account_temp and 10% on investor2', async () => { + await I_ERC20DividendCheckpoint.setWithholding( + [account_temp, account_investor2], + [BigNumber(20 * 10 ** 16), BigNumber(10 * 10 ** 16)], + { from: token_owner } + ); + }); + + it('Should not allow mismatching input lengths', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20 * 10 ** 16), BigNumber(10 * 10 ** 16)], { + from: token_owner + }), + 'tx -> failed because mismatching input lengths' + ); + }); + + it('Should not allow withholding greater than limit', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20 * 10 ** 26)], { from: token_owner }), + 'tx -> failed because withholding greater than limit' + ); + await catchRevert(I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20 * 10 ** 26), { from: token_owner }), ''); + }); + + it('Should not create dividend with more exclusions than limit', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), { from: token_owner }); + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while (limit--) addresses.push(limit); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('10', 'ether'), + 4, + addresses, + dividendName, + { from: token_owner } + ), + 'tx -> failed because too many address excluded' + ); + }); + + it('Create another new dividend with explicit checkpoint and exclusion', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + //token transfer approved in above test + let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei('10', 'ether'), + 4, + [account_investor1], + dividendName, + { from: token_owner } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, 'Dividend should be created at checkpoint 3'); + }); + + it('Should not allow excluded to pull Dividend Payment', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor1, gasPrice: 0 }), + 'tx -> failed because msg.sender is excluded' + ); + }); + + it('Investor 2 claims dividend, issuer pushes investor 1 - fails not owner', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1], { + from: account_investor2, + gasPrice: 0 + }), + 'tx -> failed because not called by the owner' + ); + }); + + it('Investor 2 claims dividend, issuer pushes investor 1 - fails bad index', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1], { + from: token_owner, + gasPrice: 0 + }), + 'tx -> failed because dividend index is not valid' + ); + }); + + it('should not calculate dividend for invalid index', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1), + 'tx -> failed because dividend index is not valid' + ); + }); + + it('should calculate dividend before the push dividend payment', async () => { + let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); + let dividendAmount3 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor3); + let dividendAmount_temp = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_temp); + assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei('0', 'ether')); + assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei('2', 'ether')); + assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei('0', 'ether')); + assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei('0.2', 'ether')); + assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei('0', 'ether')); + assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei('0.2', 'ether')); + }); + + it('Investor 2 claims dividend', async () => { + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); + await I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.8', 'ether')); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); + assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); + }); + + it('Should issuer pushes temp investor - investor1 excluded', async () => { + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(3, [account_temp, account_investor1], { from: token_owner }); + let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('0.8', 'ether')); + //Check fully claimed + assert.equal((await I_ERC20DividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); + }); + + it('should calculate dividend after the push dividend payment', async () => { + let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); + assert.equal(dividendAmount1[0].toNumber(), 0); + assert.equal(dividendAmount2[0].toNumber(), 0); + }); + + it('Should not allow reclaiming withholding tax with incorrect index', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.withdrawWithholding(300, { from: token_owner, gasPrice: 0 }), + 'tx -> failed because dividend index is not valid' + ); + }); + + it('Issuer reclaims withholding tax', async () => { + let issuerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); + await I_ERC20DividendCheckpoint.withdrawWithholding(3, { from: token_owner, gasPrice: 0 }); + let issuerBalanceAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.4', 'ether')); + }); + + it('Issuer unable to reclaim dividend (expiry not passed)', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner }), + 'tx -> failed because expiry is in the future' + ); + }); + + it('Issuer is unable to reclaim invalid dividend', async () => { + await increaseTime(11 * 24 * 60 * 60); + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(8, { from: token_owner, gasPrice: 0 }), + 'tx -> failed because dividend index is not valid' + ); + }); + + it('Investor 3 unable to pull dividend after expiry', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 }), + 'tx -> failed because expiry is in the past' + ); + }); + + it('Issuer is able to reclaim dividend after expiry', async () => { + let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); + await I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }); + let tokenOwnerAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); + assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it('Issuer is unable to reclaim already reclaimed dividend', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }), + 'tx -> failed because dividend are already reclaimed' + ); + }); + + it('Investor 3 unable to pull dividend after reclaiming', async () => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 }), + 'tx -> failed because expiry is in the past' + ); + }); + + it('Should give the right dividend index', async () => { + let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(3); + assert.equal(index[0], 2); + }); + + it('Should give the right dividend index', async () => { + let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(8); + assert.equal(index.length, 0); + }); + + it('Get the init data', async () => { + let tx = await I_ERC20DividendCheckpoint.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); + }); + + it('Should get the listed permissions', async () => { + let tx = await I_ERC20DividendCheckpoint.getPermissions.call(); + assert.equal(tx.length, 1); + }); + + describe('Test cases for the ERC20DividendCheckpointFactory', async () => { + it('should get the exact details of the factory', async () => { + assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); + assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_ERC20DividendCheckpointFactory.getVersion.call(), '1.0.0'); + assert.equal( + web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()).replace(/\u0000/g, ''), + 'ERC20DividendCheckpoint', + 'Wrong Module added' + ); + assert.equal( + await I_ERC20DividendCheckpointFactory.getDescription.call(), + 'Create ERC20 dividends for token holders at a specific checkpoint', + 'Wrong Module added' + ); + assert.equal(await I_ERC20DividendCheckpointFactory.getTitle.call(), 'ERC20 Dividend Checkpoint', 'Wrong Module added'); + assert.equal( + await I_ERC20DividendCheckpointFactory.getInstructions.call(), + 'Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created', + 'Wrong Module added' + ); + let tags = await I_ERC20DividendCheckpointFactory.getTags.call(); + assert.equal(tags.length, 3); + }); + }); + }); }); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index f87920419..92ebce81d 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -22,833 +22,864 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('EtherDividendCheckpoint', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_temp; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + let dividendName = '0x546573744469766964656e640000000000000000000000000000000000000000'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let P_EtherDividendCheckpointFactory; + let P_EtherDividendCheckpoint; + let I_EtherDividendCheckpointFactory; + let I_GeneralPermissionManager; + let I_EtherDividendCheckpoint; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_MRProxied; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + let snapId; + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const checkpointKey = 4; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let P_EtherDividendCheckpointFactory; - let P_EtherDividendCheckpoint; - let I_EtherDividendCheckpointFactory; - let I_GeneralPermissionManager; - let I_EtherDividendCheckpoint; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_MRProxied; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - let snapId; - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); + + // STEP 5: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); + + // STEP 4: Deploy the ERC20DividendCheckpoint + P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new( + I_PolyToken.address, + web3.utils.toWei('500', 'ether'), + 0, + 0, + { from: account_polymath } + ); + assert.notEqual( + P_EtherDividendCheckpointFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'ERC20DividendCheckpointFactory contract was not deployed' + ); + + // STEP 4: Deploy the EtherDividendCheckpoint + I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_EtherDividendCheckpointFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'EtherDividendCheckpointFactory contract was not deployed' + ); + + // Step 6: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + + // Step 7: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the EtherDividendCheckpointFactory + await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + + // (C) : Register the Paid EtherDividendCheckpointFactory + await I_MRProxied.registerModule(P_EtherDividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + ModuleRegistryProxy: ${ModuleRegistryProxy.address} + FeatureRegistry: ${FeatureRegistry.address} - // STEP 5: Deploy the GeneralDelegateManagerFactory + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + EtherDividendCheckpointFactory: ${I_EtherDividendCheckpointFactory.address} + ----------------------------------------------------------------------------- + `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - // STEP 4: Deploy the ERC20DividendCheckpoint - P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); - assert.notEqual( - P_EtherDividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ERC20DividendCheckpointFactory contract was not deployed" - ); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - // STEP 4: Deploy the EtherDividendCheckpoint - I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_EtherDividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "EtherDividendCheckpointFactory contract was not deployed" - ); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - // Step 6: Deploy the STFactory contract + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); - // Step 7: Deploy the SecurityTokenRegistry contract + it('Should successfully attach the ERC20DividendCheckpoint with the security token', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); + await catchRevert( + I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { from: token_owner }) + ); + }); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + it('Should successfully attach the EtherDividendCheckpoint with the security token', async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { + from: token_owner + }); + assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), + 'EtherDividendCheckpoint', + 'EtherDividendCheckpoint module was not added' + ); + P_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + it('Should successfully attach the EtherDividendCheckpoint with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, '', 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'EtherDividendCheckpoint', + 'EtherDividendCheckpoint module was not added' + ); + I_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[2].args._module); + }); + }); - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + describe('Check Dividend payouts', async () => { + it('Buy some tokens for account_investor1 (1 ETH)', async () => { + // Add the Investor in to the whitelist - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + } + ); - // STEP 5: Register the Modules with the ModuleRegistry contract + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // Jump time + await increaseTime(5000); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - // (C) : Register the EtherDividendCheckpointFactory - await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); + }); - // (C) : Register the Paid EtherDividendCheckpointFactory - await I_MRProxied.registerModule(P_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + it('Buy some tokens for account_investor2 (2 ETH)', async () => { + // Add the Investor in to the whitelist - // Printing all the contract addresses - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + } + ); - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - EtherDividendCheckpointFactory: ${I_EtherDividendCheckpointFactory.address} - ----------------------------------------------------------------------------- - `); + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + + it('Should fail in creating the dividend', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { from: token_owner })); + }); + + it('Should fail in creating the dividend', async () => { + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await catchRevert( + I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei('1.5', 'ether') + }) + ); + }); + + it('Should fail in creating the dividend', async () => { + let maturity = latestTime() - duration.days(2); + let expiry = latestTime() - duration.days(1); + await catchRevert( + I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei('1.5', 'ether') + }) + ); + }); + + it('Set withholding tax of 20% on investor 2', async () => { + await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(20 * 10 ** 16), { from: token_owner }); + }); + + it('Should fail in creating the dividend', async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + await catchRevert( + I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', { from: token_owner, value: web3.utils.toWei('1.5', 'ether') }) + ); + }); + + it('Create new dividend', async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei('1.5', 'ether') + }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, 'Dividend should be created at checkpoint 1'); + assert.equal(tx.logs[0].args._name.toString(), dividendName, 'Dividend name incorrect in event'); + }); + + it('Investor 1 transfers his token balance to investor 2', async () => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner })); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { + // Increase time by 2 day + await increaseTime(duration.days(2)); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: account_temp })); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner })); + }); + + it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { + let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); + await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner }); + let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); + assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); + assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('0.8', 'ether')); + //Check fully claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); + }); + + it('Should not allow reclaiming withholding tax with incorrect index', async () => { + await catchRevert( + I_EtherDividendCheckpoint.withdrawWithholding(300, { from: token_owner, gasPrice: 0 }), + 'tx -> failed because dividend index is not valid' + ); + }); + + it('Issuer reclaims withholding tax', async () => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.2', 'ether')); + }); + + it('No more withholding tax to withdraw', async () => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')); + }); + + it('Buy some tokens for account_temp (1 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_temp, + latestTime(), + latestTime(), + latestTime() + duration.days(20), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_temp)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Create new dividend', async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei('1.5', 'ether') + }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, 'Dividend should be created at checkpoint 2'); + }); + + it('Issuer pushes dividends fails due to passed expiry', async () => { + await increaseTime(duration.days(12)); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner })); + }); + + it('Issuer reclaims dividend', async () => { + let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }); + assert.equal(tx.logs[0].args._claimedAmount.toNumber(), web3.utils.toWei('1.5', 'ether')); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 })); + }); + + it('Still no more withholding tax to withdraw', async () => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')); + }); + + it('Buy some tokens for account_investor3 (7 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it('Create another new dividend', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei('11', 'ether') + }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, 'Dividend should be created at checkpoint 3'); + }); + + it('should investor 3 claims dividend - fails bad index', async () => { + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(5, { from: account_investor3, gasPrice: 0 })); + }); + + it('Should investor 3 claims dividend', async () => { + let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); + await I_EtherDividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }); + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it('Still no more withholding tax to withdraw', async () => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')); + }); + + it('should investor 3 claims dividend', async () => { + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 })); + }); + + it('Issuer pushes remainder', async () => { + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); + let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('2.4', 'ether')); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + //Check fully claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('11', 'ether')); + }); + + it('Issuer withdraws new withholding tax', async () => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(2, { from: token_owner, gasPrice: 0 }); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.6', 'ether')); + }); + + it('Investor 2 transfers 1 ETH of his token balance to investor 1', async () => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + }); + + it('Create another new dividend with no value - fails', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + let tx = await I_SecurityToken.createCheckpoint({ from: token_owner }); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { from: token_owner, value: 0 }) + ); + }); + + it('Create another new dividend with explicit', async () => { + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { + from: token_owner, + value: web3.utils.toWei('11', 'ether') + }) + ); + }); + + it('Create another new dividend with bad expirty - fails', async () => { + let maturity = latestTime() - duration.days(5); + let expiry = latestTime() - duration.days(2); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { + from: token_owner, + value: web3.utils.toWei('11', 'ether') + }) + ); + }); + + it('Create another new dividend with bad checkpoint in the future - fails', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, { + from: token_owner, + value: web3.utils.toWei('11', 'ether') + }) + ); + }); + + it('Should not create dividend with more exclusions than limit', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + let limit = await I_EtherDividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while (limit--) addresses.push(limit); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, addresses, dividendName, { + from: token_owner, + value: web3.utils.toWei('10', 'ether') + }), + 'tx -> failed because too many address excluded' + ); + }); + + it('Create another new dividend with explicit checkpoint and excluding account_investor1', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + //checkpoint created in above test + let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + 4, + [account_investor1], + dividendName, + { from: token_owner, value: web3.utils.toWei('10', 'ether') } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, 'Dividend should be created at checkpoint 4'); + }); + + it('Non-owner pushes investor 1 - fails', async () => { + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await catchRevert( + I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1], { + from: account_investor2, + gasPrice: 0 + }) + ); + }); + + it('issuer pushes investor 1 with bad dividend index - fails', async () => { + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await catchRevert( + I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1], { + from: token_owner, + gasPrice: 0 + }) + ); + }); + + it('should calculate dividend before the push dividend payment', async () => { + let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); + let dividendAmount3 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor3); + let dividendAmount_temp = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_temp); + //1 has 1/11th, 2 has 2/11th, 3 has 7/11th, temp has 1/11th, but 1 is excluded + assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei('0', 'ether')); + assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei('0', 'ether')); + assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei('2', 'ether')); + assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei('0.4', 'ether')); + assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei('0', 'ether')); + assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei('0', 'ether')); + }); + + it('Investor 2 claims dividend', async () => { + let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); + await I_EtherDividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.6', 'ether')); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); + assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); + }); + + it('Should issuer pushes investor 1 and temp investor', async () => { + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); + await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor1, account_temp], { from: token_owner }); + let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter2 = BigNumber(await web3.eth.getBalance(account_temp)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('1', 'ether')); + //Check fully claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); + }); + + it('should calculate dividend after the push dividend payment', async () => { + let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); + assert.equal(dividendAmount1[0].toNumber(), 0); + assert.equal(dividendAmount2[0].toNumber(), 0); + }); + + it('Issuer unable to reclaim dividend (expiry not passed)', async () => { + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner })); + }); + + it('Issuer is able to reclaim dividend after expiry', async () => { + await increaseTime(11 * 24 * 60 * 60); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, { from: token_owner, gasPrice: 0 })); + }); + + it('Issuer is able to reclaim dividend after expiry', async () => { + let tokenOwnerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }); + let tokenOwnerAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { - - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); - }); - - it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "EtherDividendCheckpoint", - "EtherDividendCheckpoint module was not added" - ); - P_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "EtherDividendCheckpoint", - "EtherDividendCheckpoint module was not added" - ); - I_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[2].args._module); - }); - }); - - describe("Check Dividend payouts", async() => { - - it("Buy some tokens for account_investor1 (1 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Buy some tokens for account_investor2 (2 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Should fail in creating the dividend", async() => { - - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner})); - }); - - it("Should fail in creating the dividend", async() => { - - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); - }); - - it("Should fail in creating the dividend", async() => { - - let maturity = latestTime() - duration.days(2); - let expiry = latestTime() - duration.days(1); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); - }); - - it("Set withholding tax of 20% on investor 2", async() => { - await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(20*10**16), {from: token_owner}); - }); - - it("Should fail in creating the dividend", async() => { - - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); - }); - - it("Create new dividend", async() => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); - assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); - }); - - it("Investor 1 transfers his token balance to investor 2", async() => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), {from: account_investor1}); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - - // Increase time by 2 day - await increaseTime(duration.days(2)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp})); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner})); - }); - - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); - await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); - let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); - assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('0.8', 'ether')); - //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); - }); - - it("Should not allow reclaiming withholding tax with incorrect index", async() => { - await catchRevert( - I_EtherDividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), - "tx -> failed because dividend index is not valid" - ); - }); - - it("Issuer reclaims withholding tax", async() => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.2', 'ether')) - }); - - it("No more withholding tax to withdraw", async() => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) - }); - - it("Buy some tokens for account_temp (1 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - latestTime(), - latestTime(), - latestTime() + duration.days(20), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_temp)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Create new dividend", async() => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 2"); - }); - - it("Issuer pushes dividends fails due to passed expiry", async() => { - - await increaseTime(duration.days(12)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); - }); - - it("Issuer reclaims dividend", async() => { - - let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); - assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000})); - }); - - it("Still no more withholding tax to withdraw", async() => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) - }); - - it("Buy some tokens for account_investor3 (7 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('7', 'ether') - ); - }); - - it("Create another new dividend", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 3"); - }); - - it("should investor 3 claims dividend - fails bad index", async() => { - - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0})); - }); - - it("Should investor 3 claims dividend", async() => { - let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); - await I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it("Still no more withholding tax to withdraw", async() => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) - }); - - it("should investor 3 claims dividend", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0})); - }); - - it("Issuer pushes remainder", async() => { - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); - let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('2.4', 'ether')); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('11', 'ether')); - }); - - it("Issuer withdraws new withholding tax", async() => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(2, {from: token_owner, gasPrice: 0}); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.6', 'ether')) - }); - - it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - }); - - it("Create another new dividend with no value - fails", async() => { - - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: 0})); - }); - - it("Create another new dividend with explicit", async() => { - - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); - }); - - it("Create another new dividend with bad expirty - fails", async() => { - - let maturity = latestTime() - duration.days(5); - let expiry = latestTime() - duration.days(2); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); - }); - - it("Create another new dividend with bad checkpoint in the future - fails", async() => { - - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); - }); - - it("Should not create dividend with more exclusions than limit", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_SecurityToken.createCheckpoint({from: token_owner}); - let limit = await I_EtherDividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber(); - let addresses = []; - addresses.push(account_temp); - while(limit--) - addresses.push(limit); - await catchRevert( - I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, addresses, dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}), - "tx -> failed because too many address excluded" - ); - }); - - it("Create another new dividend with explicit checkpoint and excluding account_investor1", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - //checkpoint created in above test - let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, [account_investor1], dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 4"); - }); - - it("Non-owner pushes investor 1 - fails", async() => { - - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0})); - }); - - it("issuer pushes investor 1 with bad dividend index - fails", async() => { - - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0})); - }); - - it("should calculate dividend before the push dividend payment", async() => { - let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); - let dividendAmount3 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor3); - let dividendAmount_temp = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_temp); - //1 has 1/11th, 2 has 2/11th, 3 has 7/11th, temp has 1/11th, but 1 is excluded - assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei("0", "ether")); - assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei("0", "ether")); - assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei("2", "ether")); - assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("0.4", "ether")); - assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei("7", "ether")); - assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei("0", "ether")); - assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei("1", "ether")); - assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0", "ether")); - }); - - it("Investor 2 claims dividend", async() => { - let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); - await I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor2, gasPrice: 0}); - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.6', 'ether')); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); - assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); - }); - - it("Should issuer pushes investor 1 and temp investor", async() => { - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); - await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor1, account_temp], {from: token_owner}); - let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter2 = BigNumber(await web3.eth.getBalance(account_temp)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('1', 'ether')); - //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); - }); - - it("should calculate dividend after the push dividend payment", async() => { - let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); - assert.equal(dividendAmount1[0].toNumber(), 0); - assert.equal(dividendAmount2[0].toNumber(), 0); - }); - - it("Issuer unable to reclaim dividend (expiry not passed)", async() => { - - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner})); - }); - - it("Issuer is able to reclaim dividend after expiry", async() => { - - await increaseTime(11 * 24 * 60 * 60); - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0})); - }); - - it("Issuer is able to reclaim dividend after expiry", async() => { - let tokenOwnerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); - let tokenOwnerAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it("Issuer is able to reclaim dividend after expiry", async() => { - - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0})); - }); - - it("Investor 3 unable to pull dividend after expiry", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0})); - }); - - it("Assign token balance to an address that can't receive funds", async() => { - - let tx = await I_GeneralTransferManager.modifyWhitelist( - I_PolyToken.address, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - }); - // Jump time - await increaseTime(5000); - // Mint some tokens - await I_SecurityToken.mint(I_PolyToken.address, web3.utils.toWei('1', 'ether'), { from: token_owner }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(I_PolyToken.address), web3.utils.toWei('1', 'ether')); - }); - - it("Create another new dividend", async() => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], dividendName, {from: token_owner, value: web3.utils.toWei('12', 'ether')}); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 6, "Dividend should be created at checkpoint 6"); - }); - - it("Should issuer pushes all dividends", async() => { - let investor1BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceBefore = BigNumber(await web3.eth.getBalance(account_temp)); - let tokenBalanceBefore = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); - - await I_EtherDividendCheckpoint.pushDividendPayment(4, 0, 10, {from: token_owner}); - - let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter = BigNumber(await web3.eth.getBalance(account_temp)); - let tokenBalanceAfter = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); - - assert.equal(investor1BalanceAfter.sub(investor1BalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), web3.utils.toWei('1.6', 'ether')); - assert.equal(investor3BalanceAfter.sub(investor3BalanceBefore).toNumber(), web3.utils.toWei('7', 'ether')); - assert.equal(tempBalanceAfter.sub(tempBalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(tokenBalanceAfter.sub(tokenBalanceBefore).toNumber(), web3.utils.toWei('0', 'ether')); - - //Check partially claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(4))[5].toNumber(), web3.utils.toWei('11', 'ether')); - }); - - it("Should give the right dividend index", async() => { - let index = await I_EtherDividendCheckpoint.getDividendIndex.call(3); - assert.equal(index[0], 2); - }); - - it("Should give the right dividend index", async() => { - let index = await I_EtherDividendCheckpoint.getDividendIndex.call(8); - assert.equal(index.length, 0); - }); - - it("Get the init data", async() => { - let tx = await I_EtherDividendCheckpoint.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); - }); - - it("Should get the listed permissions", async() => { - let tx = await I_EtherDividendCheckpoint.getPermissions.call(); - assert.equal(tx.length,1); - }); - - describe("Test cases for the EtherDividendCheckpointFactory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_EtherDividendCheckpointFactory.getType.call(), 4); - assert.equal(await I_EtherDividendCheckpointFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()) - .replace(/\u0000/g, ''), - "EtherDividendCheckpoint", - "Wrong Module added"); - assert.equal(await I_EtherDividendCheckpointFactory.getDescription.call(), - "Create ETH dividends for token holders at a specific checkpoint", - "Wrong Module added"); - assert.equal(await I_EtherDividendCheckpointFactory.getTitle.call(), - "Ether Dividend Checkpoint", - "Wrong Module added"); - assert.equal(await I_EtherDividendCheckpointFactory.getInstructions.call(), - "Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", - "Wrong Module added"); - let tags = await I_EtherDividendCheckpointFactory.getTags.call(); - assert.equal(tags.length, 3); - - }); - }); + it('Issuer is able to reclaim dividend after expiry', async () => { + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 })); + }); + + it('Investor 3 unable to pull dividend after expiry', async () => { + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 })); + }); + + it("Assign token balance to an address that can't receive funds", async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + I_PolyToken.address, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + } + ); + // Jump time + await increaseTime(5000); + // Mint some tokens + await I_SecurityToken.mint(I_PolyToken.address, web3.utils.toWei('1', 'ether'), { from: token_owner }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(I_PolyToken.address), web3.utils.toWei('1', 'ether')); + }); + it('Create another new dividend', async () => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], dividendName, { + from: token_owner, + value: web3.utils.toWei('12', 'ether') + }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 6, 'Dividend should be created at checkpoint 6'); }); + it('Should issuer pushes all dividends', async () => { + let investor1BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceBefore = BigNumber(await web3.eth.getBalance(account_temp)); + let tokenBalanceBefore = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); + + await I_EtherDividendCheckpoint.pushDividendPayment(4, 0, 10, { from: token_owner }); + + let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter = BigNumber(await web3.eth.getBalance(account_temp)); + let tokenBalanceAfter = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); + + assert.equal(investor1BalanceAfter.sub(investor1BalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), web3.utils.toWei('1.6', 'ether')); + assert.equal(investor3BalanceAfter.sub(investor3BalanceBefore).toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(tempBalanceAfter.sub(tempBalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(tokenBalanceAfter.sub(tokenBalanceBefore).toNumber(), web3.utils.toWei('0', 'ether')); + + //Check partially claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(4))[5].toNumber(), web3.utils.toWei('11', 'ether')); + }); + + it('Should give the right dividend index', async () => { + let index = await I_EtherDividendCheckpoint.getDividendIndex.call(3); + assert.equal(index[0], 2); + }); + + it('Should give the right dividend index', async () => { + let index = await I_EtherDividendCheckpoint.getDividendIndex.call(8); + assert.equal(index.length, 0); + }); + + it('Get the init data', async () => { + let tx = await I_EtherDividendCheckpoint.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); + }); + + it('Should get the listed permissions', async () => { + let tx = await I_EtherDividendCheckpoint.getPermissions.call(); + assert.equal(tx.length, 1); + }); + + describe('Test cases for the EtherDividendCheckpointFactory', async () => { + it('should get the exact details of the factory', async () => { + assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); + assert.equal(await I_EtherDividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_EtherDividendCheckpointFactory.getVersion.call(), '1.0.0'); + assert.equal( + web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()).replace(/\u0000/g, ''), + 'EtherDividendCheckpoint', + 'Wrong Module added' + ); + assert.equal( + await I_EtherDividendCheckpointFactory.getDescription.call(), + 'Create ETH dividends for token holders at a specific checkpoint', + 'Wrong Module added' + ); + assert.equal(await I_EtherDividendCheckpointFactory.getTitle.call(), 'Ether Dividend Checkpoint', 'Wrong Module added'); + assert.equal( + await I_EtherDividendCheckpointFactory.getInstructions.call(), + 'Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created', + 'Wrong Module added' + ); + let tags = await I_EtherDividendCheckpointFactory.getTags.call(); + assert.equal(tags.length, 3); + }); + }); + }); }); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index d7b042dd6..d3654f9cf 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -1,12 +1,12 @@ import latestTime from './helpers/latestTime'; -import {signData} from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; +import { signData } from './helpers/signData'; +import { pk } from './helpers/testprivateKey'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -24,208 +24,212 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('GeneralPermissionManager', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let token_owner_pk; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_delegate; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let P_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let P_GeneralPermissionManager; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_DummySTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_MRProxied; + let I_STRProxied; + let I_DummySTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + const delegateDetails = 'Hello I am legit delegate'; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // Dummy STO details + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei('10', 'ether'); + const someString = 'A string which is not used'; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + token_owner_pk = pk.account_1; + + account_investor1 = accounts[8]; + account_investor2 = accounts[9]; + account_delegate = accounts[7]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let token_owner_pk; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_delegate; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let P_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let P_GeneralPermissionManager; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_DummySTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_MRProxied; - let I_STRProxied; - let I_DummySTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - const delegateDetails = "Hello I am legit delegate"; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); - const someString = "A string which is not used"; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - token_owner_pk = pk.account_1; - - account_investor1 = accounts[8]; - account_investor2 = accounts[9]; - account_delegate = accounts[7]; - - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + // STEP 3: Deploy the ModuleRegistry - // STEP 6: Deploy the GeneralDelegateManagerFactory + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + // STEP 4: Deploy the GeneralTransferManagerFactory - assert.notEqual( - P_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - // STEP 7: Deploy the DummySTOFactory + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + // STEP 5: Deploy the GeneralDelegateManagerFactory - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" - ); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - // Step 8: Deploy the STFactory contract + // STEP 6: Deploy the GeneralDelegateManagerFactory - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new( + I_PolyToken.address, + web3.utils.toWei('500', 'ether'), + 0, + 0, + { from: account_polymath } + ); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual( + P_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - // Step 9: Deploy the SecurityTokenRegistry contract + // STEP 7: Deploy the DummySTOFactory - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'DummySTOFactory contract was not deployed' + ); + + // Step 8: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + + // Step 9: Deploy the SecurityTokenRegistry contract - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // STEP 8: Register the Modules with the ModuleRegistry contract + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // STEP 8: Register the Modules with the ModuleRegistry contract - // (B) : Register the Paid GeneralDelegateManagerFactory - await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // (B) : Register the Paid GeneralDelegateManagerFactory + await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -241,158 +245,163 @@ contract('GeneralPermissionManager', accounts => { DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it("Should successfully attach the General permission manager factory with the security token", async () => { - - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); - }); - - it("Should successfully attach the General permission manager factory with the security token", async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "GeneralPermissionManager", - "GeneralPermissionManagerFactory module was not added" - ); - P_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it("Should successfully attach the General permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "GeneralPermissionManager", - "GeneralPermissionManagerFactory module was not added" - ); - I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); - }); + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); }); - describe("General Permission Manager test cases", async() => { - - it("Get the init data", async() => { - let tx = await I_GeneralPermissionManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); - }); - - it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async() => { - - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1})); - }); - - it("Should fail to provide the permission-- because delegate is not yet added", async() => { - - await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner})); - }); - - it("Should add the permission to the delegate", async() => { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); - assert.equal(tx.logs[0].args._delegate, account_delegate); - }); - - it("Should fail to provide the permission", async() => { - - await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1})); - }); - - it("Should check the permission", async() => { - assert.isFalse(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); - }); - - it("Should provide the permission", async() => { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); - assert.equal(tx.logs[0].args._delegate, account_delegate); - }); - - it("Should check the permission", async() => { - assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); - }); - - it("Should check the delegate details", async() => { - assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)) - .replace(/\u0000/g, ''), - delegateDetails, - "Wrong delegate address get checked"); - }); - - it("Should get the permission of the general permission manager contract", async() => { - let tx = await I_GeneralPermissionManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]) - .replace(/\u0000/g, ''), - "CHANGE_PERMISSION", - "Wrong permissions"); - }); + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - describe("General Permission Manager Factory test cases", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); - assert.equal(await I_GeneralPermissionManagerFactory.getType.call(),1); - assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "GeneralPermissionManager", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getDescription.call(), - "Manage permissions within the Security Token and attached modules", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), - "General Permission Manager", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getInstructions.call(), - "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", - "Wrong Module added"); - - }); - - it("Should get the tags of the factory", async() => { - let tags = await I_GeneralPermissionManagerFactory.getTags.call(); - assert.equal(tags.length,0); - }); + it('Should successfully attach the General permission manager factory with the security token', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); + await catchRevert( + I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, '0x', web3.utils.toWei('500', 'ether'), 0, { + from: token_owner + }) + ); + }); + + it('Should successfully attach the General permission manager factory with the security token', async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, '0x', web3.utils.toWei('500', 'ether'), 0, { + from: token_owner + }); + assert.equal(tx.logs[3].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), + 'GeneralPermissionManager', + 'GeneralPermissionManagerFactory module was not added' + ); + P_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it('Should successfully attach the General permission manager factory with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '0x', 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'GeneralPermissionManager', + 'GeneralPermissionManagerFactory module was not added' + ); + I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); + }); + }); + + describe('General Permission Manager test cases', async () => { + it('Get the init data', async () => { + let tx = await I_GeneralPermissionManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); }); + it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async () => { + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1 })); + }); + + it('Should fail to provide the permission-- because delegate is not yet added', async () => { + await catchRevert( + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'WHITELIST', true, { + from: token_owner + }) + ); + }); + + it('Should add the permission to the delegate', async () => { + let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); + assert.equal(tx.logs[0].args._delegate, account_delegate); + }); + + it('Should fail to provide the permission', async () => { + await catchRevert( + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'WHITELIST', true, { + from: account_investor1 + }) + ); + }); + + it('Should check the permission', async () => { + assert.isFalse( + await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, 'WHITELIST') + ); + }); + + it('Should provide the permission', async () => { + let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'WHITELIST', true, { + from: token_owner + }); + assert.equal(tx.logs[0].args._delegate, account_delegate); + }); + + it('Should check the permission', async () => { + assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, 'WHITELIST')); + }); + + it('Should check the delegate details', async () => { + assert.equal( + web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)).replace(/\u0000/g, ''), + delegateDetails, + 'Wrong delegate address get checked' + ); + }); + + it('Should get the permission of the general permission manager contract', async () => { + let tx = await I_GeneralPermissionManager.getPermissions.call(); + assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ''), 'CHANGE_PERMISSION', 'Wrong permissions'); + }); + }); + + describe('General Permission Manager Factory test cases', async () => { + it('should get the exact details of the factory', async () => { + assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(), 0); + assert.equal(await I_GeneralPermissionManagerFactory.getType.call(), 1); + assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), '1.0.0'); + assert.equal( + web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()).replace(/\u0000/g, ''), + 'GeneralPermissionManager', + 'Wrong Module added' + ); + assert.equal( + await I_GeneralPermissionManagerFactory.getDescription.call(), + 'Manage permissions within the Security Token and attached modules', + 'Wrong Module added' + ); + assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), 'General Permission Manager', 'Wrong Module added'); + assert.equal( + await I_GeneralPermissionManagerFactory.getInstructions.call(), + 'Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.', + 'Wrong Module added' + ); + }); + + it('Should get the tags of the factory', async () => { + let tags = await I_GeneralPermissionManagerFactory.getTags.call(); + assert.equal(tags.length, 0); + }); + }); }); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 50c587aa4..e8dad9143 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -1,12 +1,12 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import {signData} from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; +import { signData } from './helpers/signData'; +import { pk } from './helpers/testprivateKey'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -24,195 +24,194 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('GeneralTransferManager', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let token_owner_pk; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_delegate; + let account_affiliates1; + let account_affiliates2; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_DummySTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_STRProxied; + let I_MRProxied; + let I_DummySTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // Dummy STO details + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei('10', 'ether'); + const someString = 'A string which is not used'; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + token_owner_pk = pk.account_1; + + account_investor1 = accounts[8]; + account_investor2 = accounts[9]; + account_delegate = accounts[7]; + account_investor4 = accounts[6]; + + account_affiliates1 = accounts[3]; + account_affiliates2 = accounts[4]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let token_owner_pk; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_delegate; - let account_affiliates1; - let account_affiliates2; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_DummySTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_STRProxied; - let I_MRProxied; - let I_DummySTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); - const someString = "A string which is not used"; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - token_owner_pk = pk.account_1; - - account_investor1 = accounts[8]; - account_investor2 = accounts[9]; - account_delegate = accounts[7]; - account_investor4 = accounts[6]; - - account_affiliates1 = accounts[3]; - account_affiliates2 = accounts[4]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the DummySTOFactory - - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" - ); + // STEP 3: Deploy the GeneralDelegateManagerFactory - // Step 8: Deploy the STFactory contract + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + // STEP 4: Deploy the DummySTOFactory - // Step 9: Deploy the SecurityTokenRegistry contract + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'DummySTOFactory contract was not deployed' + ); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + // Step 8: Deploy the STFactory contract - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - // STEP 5: Register the Modules with the ModuleRegistry contract + // Step 9: Deploy the SecurityTokenRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Printing all the contract addresses - console.log(` + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -228,506 +227,479 @@ contract('GeneralTransferManager', accounts => { DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); + + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it('Should whitelist the affiliates before the STO attached', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelistMulti( + [account_affiliates1, account_affiliates2], + [latestTime() + duration.days(30), latestTime() + duration.days(30)], + [latestTime() + duration.days(90), latestTime() + duration.days(90)], + [latestTime() + duration.years(1), latestTime() + duration.years(1)], + [false, false], + { + from: account_issuer, + gas: 6000000 + } + ); + assert.equal(tx.logs[0].args._investor, account_affiliates1); + assert.equal(tx.logs[1].args._investor, account_affiliates2); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - it("Should whitelist the affiliates before the STO attached", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelistMulti( - [account_affiliates1, account_affiliates2], - [(latestTime() + duration.days(30)),(latestTime() + duration.days(30))], - [(latestTime() + duration.days(90)),(latestTime() + duration.days(90))], - [(latestTime() + duration.years(1)),(latestTime() + duration.years(1))], - [false, false], - { - from: account_issuer, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_affiliates1); - assert.equal(tx.logs[1].args._investor, account_affiliates2); - }); - - it("Should mint the tokens to the affiliates", async () => { - await I_SecurityToken.mintMulti([account_affiliates1, account_affiliates2], [(100 * Math.pow(10, 18)), (100 * Math.pow(10, 18))], { from: account_issuer, gas:6000000 }); - assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - }); - - it("Should successfully attach the STO factory with the security token", async () => { - let bytesSTO = encodeModuleCall(STOParameters, [latestTime() + duration.seconds(1000), latestTime() + duration.days(40), cap, someString]); - const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), stoKey, "DummySTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "DummySTO", - "DummySTOFactory module was not added" - ); - I_DummySTO = DummySTO.at(tx.logs[2].args._module); - }); - - it("Should successfully attach the permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, 0, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "GeneralPermissionManager", - "GeneralPermissionManager module was not added" - ); - I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); - }); - - }); - - describe("Buy tokens using on-chain whitelist", async() => { - - it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - - await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }); - - it("Should Buy the tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should fail in buying the token from the STO", async() => { - - await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }); - - it("Should fail in investing the money in STO -- expiry limit reached", async() => { - - await increaseTime(duration.days(10)); - - await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + it('Should mint the tokens to the affiliates', async () => { + await I_SecurityToken.mintMulti([account_affiliates1, account_affiliates2], [100 * Math.pow(10, 18), 100 * Math.pow(10, 18)], { + from: account_issuer, + gas: 6000000 + }); + assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + }); + + it('Should successfully attach the STO factory with the security token', async () => { + let bytesSTO = encodeModuleCall(STOParameters, [ + latestTime() + duration.seconds(1000), + latestTime() + duration.days(40), + cap, + someString + ]); + const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), stoKey, "DummySTO doesn't get deployed"); + assert.equal(web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), 'DummySTO', 'DummySTOFactory module was not added'); + I_DummySTO = DummySTO.at(tx.logs[2].args._module); + }); + + it('Should successfully attach the permission manager factory with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, 0, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'GeneralPermissionManager', + 'GeneralPermissionManager module was not added' + ); + I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); + }); + }); + + describe('Buy tokens using on-chain whitelist', async () => { + it('Should buy the tokens -- Failed due to investor is not in the whitelist', async () => { + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + }); + + it('Should Buy the tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Should fail in buying the token from the STO', async () => { + await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + }); + + it('Should fail in investing the money in STO -- expiry limit reached', async () => { + await increaseTime(duration.days(10)); + + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + }); + }); + + describe('Buy tokens using off-chain whitelist', async () => { + it('Should buy the tokens -- Failed due to investor is not in the whitelist', async () => { + await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner })); + }); + + it('Should buy the tokens -- Failed due to incorrect signature input', async () => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime(); + let validTo = latestTime() + duration.days(5); + const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistSigned(account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, v, r, s, { + from: account_investor2, + gas: 6000000 }) + ); + }); + it('Should buy the tokens -- Failed due to incorrect signature timing', async () => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime() - 100; + let validTo = latestTime() - 1; + const sig = signData( + I_GeneralTransferManager.address, + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + token_owner_pk + ); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistSigned(account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, v, r, s, { + from: account_investor2, + gas: 6000000 + }) + ); }); - describe("Buy tokens using off-chain whitelist", async() => { - - it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - - await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }); - - it("Should buy the tokens -- Failed due to incorrect signature input", async() => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime(); - let validTo = latestTime() + duration.days(5); - const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - - - await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - })); - - }); - - it("Should buy the tokens -- Failed due to incorrect signature timing", async() => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime() - 100; - let validTo = latestTime() - 1; - const sig = signData(I_GeneralTransferManager.address, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - - - await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - })); - - }); - - it("Should buy the tokens -- Failed due to incorrect signature signer", async() => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime(); - let validTo = latestTime() + (60 * 60); - - const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200'); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - - - await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - })); - - }); - - it("Should Buy the tokens", async() => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime(); - let validTo = latestTime() + duration.days(5); - const sig = signData(I_GeneralTransferManager.address, account_investor2, latestTime(), latestTime() + duration.days(80), expiryTime + duration.days(200), true, validFrom, validTo, token_owner_pk); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - let tx = await I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - latestTime(), - latestTime() + duration.days(80), - expiryTime + duration.days(200), - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(10000); - // Mint some tokens - - await I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - - }); - - it("Should fail in changing the signing address", async() => { - - await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_investor4})); - }); - - it("Should get the permission", async() => { - let perm = await I_GeneralTransferManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), "WHITELIST"); - assert.equal(web3.utils.toAscii(perm[1]).replace(/\u0000/g, ''), "FLAGS"); - }); - - it("Should provide the permission and change the signing address", async() => { - let log = await I_GeneralPermissionManager.addPermission(account_delegate, "My details", {from: token_owner}); - assert.equal(log.logs[0].args._delegate, account_delegate); - - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FLAGS", true, {from: token_owner}); - - assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "FLAGS")); - - let tx = await I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_delegate}); - assert.equal(tx.logs[0].args._signingAddress, account_polymath); - }); - - it("Should fail to pull fees as no budget set", async() => { - - - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); - }); - - it("Should set a budget for the GeneralTransferManager", async() => { - await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), {from: token_owner}); - - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); - await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); - await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), {from: token_owner}); - }); - - - it("Factory owner should pull fees - fails as not permissioned by issuer", async() => { - - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate})); - }); - - it("Should change the Issuance address", async() => { - let tx = await I_GeneralTransferManager.changeIssuanceAddress(account_investor2, {from: account_delegate}); - assert.equal(tx.logs[0].args._issuanceAddress, account_investor2); - }); - - it("Should unpause the transfers", async() => { - await I_GeneralTransferManager.unpause({from: token_owner}); - - assert.isFalse(await I_GeneralTransferManager.paused.call()); - }); - - it("Should get the init function", async() => { - let byte = await I_GeneralTransferManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); - }); - - }); - - describe("WhiteList that addresses", async () => { - - it("Should fail in adding the investors in whitelist", async() => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime, toTime], - [expiryTime, expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - )); - }); - - it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime], - [toTime, toTime], - [expiryTime, expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - )); - }); - - it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime], - [expiryTime, expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - )); - }); - - it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime, toTime], - [expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - )); - }); - - it("Should successfully add the investors in whitelist", async() => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - let tx = await I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime, toTime], - [expiryTime, expiryTime], - [true, true], - { - from: token_owner, - gas: 6000000 - } - ); - assert.equal(tx.logs[1].args._investor, account_investor4); - }); - }); - - describe("General Transfer Manager Factory test cases", async() => { - - it("Should get the exact details of the factory", async() => { - assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_GeneralTransferManagerFactory.getType.call(),2); - assert.equal(web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "GeneralTransferManager", - "Wrong Module added"); - assert.equal(await I_GeneralTransferManagerFactory.getDescription.call(), - "Manage transfers using a time based whitelist", - "Wrong Module added"); - assert.equal(await I_GeneralTransferManagerFactory.getTitle.call(), - "General Transfer Manager", - "Wrong Module added"); - assert.equal(await I_GeneralTransferManagerFactory.getInstructions.call(), - "Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters.", - "Wrong Module added"); - - }); - - it("Should get the tags of the factory", async() => { - let tags = await I_GeneralTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "General"); - }); - }); - - describe("Dummy STO Factory test cases", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_DummySTOFactory.setupCost.call(),0); - assert.equal(await I_DummySTOFactory.getType.call(),3); - assert.equal(web3.utils.toAscii(await I_DummySTOFactory.getName.call()) - .replace(/\u0000/g, ''), - "DummySTO", - "Wrong Module added"); - assert.equal(await I_DummySTOFactory.getDescription.call(), - "Dummy STO", - "Wrong Module added"); - assert.equal(await I_DummySTOFactory.getTitle.call(), - "Dummy STO", - "Wrong Module added"); - assert.equal(await I_DummySTOFactory.getInstructions.call(), - "Dummy STO - you can mint tokens at will", - "Wrong Module added"); - - }); - - it("Should get the tags of the factory", async() => { - let tags = await I_DummySTOFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "Dummy"); - }); - }); - - describe("Test cases for the get functions of the dummy sto", async() => { - - it("Should get the raised amount of ether", async() => { - assert.equal(await I_DummySTO.getRaised.call(0), web3.utils.toWei('0','ether')); - }); - - it("Should get the raised amount of poly", async() => { - assert.equal((await I_DummySTO.getRaised.call(1)).toNumber(), web3.utils.toWei('0','ether')); - }); - - it("Should get the investors", async() => { - assert.equal((await I_DummySTO.investorCount.call()).toNumber(), 2); - }); - - it("Should get the listed permissions", async() => { - let tx = await I_DummySTO.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ''), "ADMIN"); - }); + it('Should buy the tokens -- Failed due to incorrect signature signer', async () => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime(); + let validTo = latestTime() + 60 * 60; + + const sig = signData( + account_investor2, + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200' + ); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistSigned(account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, v, r, s, { + from: account_investor2, + gas: 6000000 + }) + ); }); + it('Should Buy the tokens', async () => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime(); + let validTo = latestTime() + duration.days(5); + const sig = signData( + I_GeneralTransferManager.address, + account_investor2, + latestTime(), + latestTime() + duration.days(80), + expiryTime + duration.days(200), + true, + validFrom, + validTo, + token_owner_pk + ); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + let tx = await I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + latestTime(), + latestTime() + duration.days(80), + expiryTime + duration.days(200), + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Jump time + await increaseTime(10000); + // Mint some tokens + + await I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Should fail in changing the signing address', async () => { + await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, { from: account_investor4 })); + }); + + it('Should get the permission', async () => { + let perm = await I_GeneralTransferManager.getPermissions.call(); + assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), 'WHITELIST'); + assert.equal(web3.utils.toAscii(perm[1]).replace(/\u0000/g, ''), 'FLAGS'); + }); + + it('Should provide the permission and change the signing address', async () => { + let log = await I_GeneralPermissionManager.addPermission(account_delegate, 'My details', { from: token_owner }); + assert.equal(log.logs[0].args._delegate, account_delegate); + + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'FLAGS', true, { + from: token_owner + }); + + assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, 'FLAGS')); + + let tx = await I_GeneralTransferManager.changeSigningAddress(account_polymath, { from: account_delegate }); + assert.equal(tx.logs[0].args._signingAddress, account_polymath); + }); + + it('Should fail to pull fees as no budget set', async () => { + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1', 'ether'), { from: account_polymath })); + }); + + it('Should set a budget for the GeneralTransferManager', async () => { + await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), { from: token_owner }); + + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1', 'ether'), { from: account_polymath })); + await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); + await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), { from: token_owner }); + }); + + it('Factory owner should pull fees - fails as not permissioned by issuer', async () => { + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1', 'ether'), { from: account_delegate })); + }); + + it('Should change the Issuance address', async () => { + let tx = await I_GeneralTransferManager.changeIssuanceAddress(account_investor2, { from: account_delegate }); + assert.equal(tx.logs[0].args._issuanceAddress, account_investor2); + }); + + it('Should unpause the transfers', async () => { + await I_GeneralTransferManager.unpause({ from: token_owner }); + + assert.isFalse(await I_GeneralTransferManager.paused.call()); + }); + + it('Should get the init function', async () => { + let byte = await I_GeneralTransferManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); + }); + }); + + describe('WhiteList that addresses', async () => { + it('Should fail in adding the investors in whitelist', async () => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime, toTime], + [expiryTime, expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + ) + ); + }); + + it('Should fail in adding the investors in whitelist -- array length mismatch', async () => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime], + [toTime, toTime], + [expiryTime, expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + ) + ); + }); + + it('Should fail in adding the investors in whitelist -- array length mismatch', async () => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime], + [expiryTime, expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + ) + ); + }); + + it('Should fail in adding the investors in whitelist -- array length mismatch', async () => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime, toTime], + [expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + ) + ); + }); + + it('Should successfully add the investors in whitelist', async () => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + let tx = await I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime, toTime], + [expiryTime, expiryTime], + [true, true], + { + from: token_owner, + gas: 6000000 + } + ); + assert.equal(tx.logs[1].args._investor, account_investor4); + }); + }); + + describe('General Transfer Manager Factory test cases', async () => { + it('Should get the exact details of the factory', async () => { + assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(), 0); + assert.equal(await I_GeneralTransferManagerFactory.getType.call(), 2); + assert.equal( + web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()).replace(/\u0000/g, ''), + 'GeneralTransferManager', + 'Wrong Module added' + ); + assert.equal( + await I_GeneralTransferManagerFactory.getDescription.call(), + 'Manage transfers using a time based whitelist', + 'Wrong Module added' + ); + assert.equal(await I_GeneralTransferManagerFactory.getTitle.call(), 'General Transfer Manager', 'Wrong Module added'); + assert.equal( + await I_GeneralTransferManagerFactory.getInstructions.call(), + 'Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters.', + 'Wrong Module added' + ); + }); + + it('Should get the tags of the factory', async () => { + let tags = await I_GeneralTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'General'); + }); + }); + + describe('Dummy STO Factory test cases', async () => { + it('should get the exact details of the factory', async () => { + assert.equal(await I_DummySTOFactory.setupCost.call(), 0); + assert.equal(await I_DummySTOFactory.getType.call(), 3); + assert.equal(web3.utils.toAscii(await I_DummySTOFactory.getName.call()).replace(/\u0000/g, ''), 'DummySTO', 'Wrong Module added'); + assert.equal(await I_DummySTOFactory.getDescription.call(), 'Dummy STO', 'Wrong Module added'); + assert.equal(await I_DummySTOFactory.getTitle.call(), 'Dummy STO', 'Wrong Module added'); + assert.equal(await I_DummySTOFactory.getInstructions.call(), 'Dummy STO - you can mint tokens at will', 'Wrong Module added'); + }); + + it('Should get the tags of the factory', async () => { + let tags = await I_DummySTOFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Dummy'); + }); + }); + + describe('Test cases for the get functions of the dummy sto', async () => { + it('Should get the raised amount of ether', async () => { + assert.equal(await I_DummySTO.getRaised.call(0), web3.utils.toWei('0', 'ether')); + }); + + it('Should get the raised amount of poly', async () => { + assert.equal((await I_DummySTO.getRaised.call(1)).toNumber(), web3.utils.toWei('0', 'ether')); + }); + + it('Should get the investors', async () => { + assert.equal((await I_DummySTO.investorCount.call()).toNumber(), 2); + }); + + it('Should get the listed permissions', async () => { + let tx = await I_DummySTO.getPermissions.call(); + assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ''), 'ADMIN'); + }); + }); }); diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 9369f3eba..a1a91144a 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -1,6 +1,6 @@ import { encodeProxyCall, encodeModuleCall } from './encodeCall'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -15,151 +15,145 @@ const PolyToken = artifacts.require('./PolyToken.sol'); const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - - // Contract Instance Declaration - let I_GeneralTransferManagerFactory; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_SecurityToken; - let I_PolyToken; - let I_STFactory; - let I_PolymathRegistry; - let I_SecurityTokenRegistryProxy; - let I_STRProxied; - let I_MRProxied; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port + +// Contract Instance Declaration +let I_GeneralTransferManagerFactory; +let I_GeneralTransferManager; +let I_ModuleRegistryProxy; +let I_ModuleRegistry; +let I_FeatureRegistry; +let I_SecurityTokenRegistry; +let I_SecurityToken; +let I_PolyToken; +let I_STFactory; +let I_PolymathRegistry; +let I_SecurityTokenRegistryProxy; +let I_STRProxied; +let I_MRProxied; + +// Initial fee for ticker registry and security token registry +const initRegFee = web3.utils.toWei('250'); + +const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; +const MRProxyParameters = ['address', 'address']; export async function setUpPolymathNetwork(account_polymath, token_owner) { - // ----------- POLYMATH NETWORK Configuration ------------ - // Step 1: Deploy the PolyToken and PolymathRegistry - let a = await deployPolyRegistryAndPolyToken(account_polymath, token_owner); - // Step 2: Deploy the FeatureRegistry - let b = await deployFeatureRegistry(account_polymath); - // STEP 3: Deploy the ModuleRegistry - let c = await deployModuleRegistry(account_polymath); - // STEP 4: Deploy the GeneralTransferManagerFactory - let d = await deployGTM(account_polymath); - // Step 6: Deploy the STversionProxy contract - let e = await deploySTFactory(account_polymath); - // Step 7: Deploy the SecurityTokenRegistry - let f = await deploySTR(account_polymath); - // Step 8: update the registries addresses from the PolymathRegistry contract - await setInPolymathRegistry(account_polymath); - // STEP 9: Register the Modules with the ModuleRegistry contract - await registerGTM(account_polymath); - let tempArray = new Array(a, b, c, d, e, f); - return mergeReturn(tempArray); - + // ----------- POLYMATH NETWORK Configuration ------------ + // Step 1: Deploy the PolyToken and PolymathRegistry + let a = await deployPolyRegistryAndPolyToken(account_polymath, token_owner); + // Step 2: Deploy the FeatureRegistry + let b = await deployFeatureRegistry(account_polymath); + // STEP 3: Deploy the ModuleRegistry + let c = await deployModuleRegistry(account_polymath); + // STEP 4: Deploy the GeneralTransferManagerFactory + let d = await deployGTM(account_polymath); + // Step 6: Deploy the STversionProxy contract + let e = await deploySTFactory(account_polymath); + // Step 7: Deploy the SecurityTokenRegistry + let f = await deploySTR(account_polymath); + // Step 8: update the registries addresses from the PolymathRegistry contract + await setInPolymathRegistry(account_polymath); + // STEP 9: Register the Modules with the ModuleRegistry contract + await registerGTM(account_polymath); + let tempArray = new Array(a, b, c, d, e, f); + return mergeReturn(tempArray); } - function mergeReturn(returnData) { - let returnArray = new Array(); - for (let i = 0; i < returnData.length; i++) { - for (let j = 0; j < returnData[i].length; j++) { - returnArray.push(returnData[i][j]); - } + let returnArray = new Array(); + for (let i = 0; i < returnData.length; i++) { + for (let j = 0; j < returnData[i].length; j++) { + returnArray.push(returnData[i][j]); } - return returnArray; - + } + return returnArray; } - async function deployPolyRegistryAndPolyToken(account_polymath, token_owner) { - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - return new Array(I_PolymathRegistry, I_PolyToken); + return new Array(I_PolymathRegistry, I_PolyToken); } async function deployFeatureRegistry(account_polymath) { + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - return new Array(I_FeatureRegistry) + return new Array(I_FeatureRegistry); } async function deployModuleRegistry(account_polymath) { - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - return new Array(I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + return new Array(I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied); } async function deployGTM(account_polymath) { - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - return new Array(I_GeneralTransferManagerFactory); + return new Array(I_GeneralTransferManagerFactory); } async function deploySTFactory(account_polymath) { + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - return new Array(I_STFactory); + return new Array(I_STFactory); } async function deploySTR(account_polymath) { - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 9 (a): Deploy the proxy - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - return new Array(I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 9 (a): Deploy the proxy + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + return new Array(I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied); } async function setInPolymathRegistry(account_polymath) { - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); } - + async function registerGTM(account_polymath) { - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); } diff --git a/test/helpers/encodeCall.js b/test/helpers/encodeCall.js index 6a48f12a1..644c979a6 100644 --- a/test/helpers/encodeCall.js +++ b/test/helpers/encodeCall.js @@ -1,14 +1,13 @@ -const abi = require('ethereumjs-abi') +const abi = require('ethereumjs-abi'); export function encodeProxyCall(parametersType, values) { - const methodId = abi.methodID("initialize", parametersType).toString('hex'); + const methodId = abi.methodID('initialize', parametersType).toString('hex'); const params = abi.rawEncode(parametersType, values).toString('hex'); return '0x' + methodId + params; } - export function encodeModuleCall(parametersType, values) { - const methodId = abi.methodID("configure", parametersType).toString('hex'); + const methodId = abi.methodID('configure', parametersType).toString('hex'); const params = abi.rawEncode(parametersType, values).toString('hex'); return '0x' + methodId + params; -} \ No newline at end of file +} diff --git a/test/helpers/exceptions.js b/test/helpers/exceptions.js index bdeda1472..5c213a869 100644 --- a/test/helpers/exceptions.js +++ b/test/helpers/exceptions.js @@ -10,22 +10,12 @@ async function tryCatch(promise, message) { try { assert( error.message.startsWith(PREFIX + message), - "Expected an error starting with '" + - PREFIX + - message + - "' but got '" + - error.message + - "' instead" + "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead" ); } catch (err) { assert( error.message.startsWith(PREFIX2 + message), - "Expected an error starting with '" + - PREFIX + - message + - "' but got '" + - error.message + - "' instead" + "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead" ); } } @@ -53,4 +43,4 @@ module.exports = { catchStaticStateChange: async function(promise) { await tryCatch(promise, 'static state change'); } -}; \ No newline at end of file +}; diff --git a/test/helpers/latestTime.js b/test/helpers/latestTime.js index 5e39a0355..bdc97053a 100644 --- a/test/helpers/latestTime.js +++ b/test/helpers/latestTime.js @@ -1,5 +1,4 @@ // Returns the time of the last mined block in seconds -export default function latestTime () { - return web3.eth.getBlock('latest').timestamp; - } - \ No newline at end of file +export default function latestTime() { + return web3.eth.getBlock('latest').timestamp; +} diff --git a/test/helpers/signData.js b/test/helpers/signData.js index 62b040719..738505df9 100644 --- a/test/helpers/signData.js +++ b/test/helpers/signData.js @@ -4,20 +4,18 @@ const ethUtil = require('ethereumjs-util'); //this, _investor, _fromTime, _toTime, _validTo function signData(tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo, pk) { - let packedData = utils.solidityKeccak256( - [ "address", "address", "uint256", "uint256", "uint256", "bool", "uint256", "uint256" ], - [ tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo ] - ).slice(2); + let packedData = utils + .solidityKeccak256( + ['address', 'address', 'uint256', 'uint256', 'uint256', 'bool', 'uint256', 'uint256'], + [tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo] + ) + .slice(2); packedData = new Buffer(packedData, 'hex'); - packedData = Buffer.concat([ - new Buffer(`\x19Ethereum Signed Message:\n${packedData.length.toString()}`), - packedData]); + packedData = Buffer.concat([new Buffer(`\x19Ethereum Signed Message:\n${packedData.length.toString()}`), packedData]); packedData = web3.sha3(`0x${packedData.toString('hex')}`, { encoding: 'hex' }); - return ethUtil.ecsign( - new Buffer(packedData.slice(2), 'hex'), - new Buffer(pk, 'hex')); + return ethUtil.ecsign(new Buffer(packedData.slice(2), 'hex'), new Buffer(pk, 'hex')); } module.exports = { signData -} +}; diff --git a/test/helpers/testprivateKey.js b/test/helpers/testprivateKey.js index 16e464cd1..ae671f11d 100644 --- a/test/helpers/testprivateKey.js +++ b/test/helpers/testprivateKey.js @@ -1,6 +1,6 @@ export const pk = { - account_0 :'2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200', - account_1 :'2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201' -} + account_0: '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200', + account_1: '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201' +}; export default { pk }; diff --git a/test/helpers/time.js b/test/helpers/time.js index 37533c92b..717bed9d0 100644 --- a/test/helpers/time.js +++ b/test/helpers/time.js @@ -2,61 +2,73 @@ // aren’t included within the original RPC specification. // See https://github.com/ethereumjs/testrpc#implemented-methods -function increaseTime (duration) { - const id = Date.now(); - - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ +function increaseTime(duration) { + const id = Date.now(); + + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync( + { jsonrpc: '2.0', method: 'evm_increaseTime', params: [duration], - id: id, - }, err1 => { + id: id + }, + err1 => { if (err1) return reject(err1); - - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_mine', - id: id + 1, - }, (err2, res) => { - return err2 ? reject(err2) : resolve(res); - }); - }); - }); - } -export default function takeSnapshot() { - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ + web3.currentProvider.sendAsync( + { jsonrpc: '2.0', - method: 'evm_snapshot', - params: [], - id: new Date().getTime() - }, (err, result) => { - if (err) { - return reject(err); - } - - resolve(result.result); - }); - }); -}; + method: 'evm_mine', + id: id + 1 + }, + (err2, res) => { + return err2 ? reject(err2) : resolve(res); + } + ); + } + ); + }); +} + +export default function takeSnapshot() { + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync( + { + jsonrpc: '2.0', + method: 'evm_snapshot', + params: [], + id: new Date().getTime() + }, + (err, result) => { + if (err) { + return reject(err); + } + + resolve(result.result); + } + ); + }); +} function revertToSnapshot(snapShotId) { - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_revert', - params: [snapShotId], - id: new Date().getTime() - }, (err) => { - if (err) { - return reject(err); - } - - resolve(); - }); - }); -}; - - export { increaseTime, takeSnapshot, revertToSnapshot }; \ No newline at end of file + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync( + { + jsonrpc: '2.0', + method: 'evm_revert', + params: [snapShotId], + id: new Date().getTime() + }, + err => { + if (err) { + return reject(err); + } + + resolve(); + } + ); + }); +} + +export { increaseTime, takeSnapshot, revertToSnapshot }; diff --git a/test/helpers/utils.js b/test/helpers/utils.js index c1c900de1..224a52c48 100644 --- a/test/helpers/utils.js +++ b/test/helpers/utils.js @@ -1,66 +1,73 @@ /* global assert */ -var _ = require("lodash"); +var _ = require('lodash'); function isException(error) { - let strError = error.toString(); - return strError.includes('invalid opcode') || strError.includes('invalid JUMP') || strError.includes('revert'); + let strError = error.toString(); + return strError.includes('invalid opcode') || strError.includes('invalid JUMP') || strError.includes('revert'); } function ensureException(error) { - assert(isException(error), error.toString()); + assert(isException(error), error.toString()); } -async function timeDifference(timestamp1,timestamp2) { - var difference = timestamp1 - timestamp2; - return difference; +async function timeDifference(timestamp1, timestamp2) { + var difference = timestamp1 - timestamp2; + return difference; } function convertHex(hexx) { - var hex = hexx.toString(); //force conversion - var str = ''; - for (var i = 0; i < hex.length; i += 2) { - let char = String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - if (char != '\u0000') str += char; - } - return str; + var hex = hexx.toString(); //force conversion + var str = ''; + for (var i = 0; i < hex.length; i += 2) { + let char = String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + if (char != '\u0000') str += char; } + return str; +} -export { - ensureException, - timeDifference, - convertHex } +export { ensureException, timeDifference, convertHex }; export const duration = { - seconds: function (val) { return val; }, - minutes: function (val) { return val * this.seconds(60); }, - hours: function (val) { return val * this.minutes(60); }, - days: function (val) { return val * this.hours(24); }, - weeks: function (val) { return val * this.days(7); }, - years: function (val) { return val * this.days(365); }, - }; - + seconds: function(val) { + return val; + }, + minutes: function(val) { + return val * this.seconds(60); + }, + hours: function(val) { + return val * this.minutes(60); + }, + days: function(val) { + return val * this.hours(24); + }, + weeks: function(val) { + return val * this.days(7); + }, + years: function(val) { + return val * this.days(365); + } +}; /** -* Helper to wait for log emission. -* @param {Object} _event The event to wait for. -*/ + * Helper to wait for log emission. + * @param {Object} _event The event to wait for. + */ export function promisifyLogWatch(_event, _times) { - return new Promise((resolve, reject) => { - let i = 0; - _event.watch((error, log) => { - if (error !== null) - reject(error); - i = i + 1; - console.log("Received event: " + i + " out of: " + _times); - if (i == _times) { - _event.stopWatching(); - resolve(log); - } - }); - }); - } + return new Promise((resolve, reject) => { + let i = 0; + _event.watch((error, log) => { + if (error !== null) reject(error); + i = i + 1; + console.log('Received event: ' + i + ' out of: ' + _times); + if (i == _times) { + _event.stopWatching(); + resolve(log); + } + }); + }); +} - export function latestBlock () { - return web3.eth.getBlock('latest').number; - } \ No newline at end of file +export function latestBlock() { + return web3.eth.getBlock('latest').number; +} diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 4cfe448d3..cb81822fb 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -3,7 +3,7 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -21,192 +21,189 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('Issuance', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_fundsReceiver; + let account_delegate; + let blockNo; + let balanceOfReceiver; + let message = 'Transaction Should Fail!'; + const TM_Perm = 'WHITELIST'; + const delegateDetails = 'I am delegate'; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_CappedSTOFactory; + let I_MRProxied; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_CappedSTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = 'Demo Token'; + const symbol = 'DET'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // Capped STO details + //let startTime; // Start time will be 5000 seconds more than the latest time + //let endTime; // Add 30 days more + const cap = web3.utils.toWei('10000'); + const rate = 1000; + const fundRaiseType = [0]; + const cappedSTOSetupCost = web3.utils.toWei('20000', 'ether'); + const maxCost = cappedSTOSetupCost; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[3]; + account_investor2 = accounts[2]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + token_owner = account_issuer; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); + // STEP 3: Deploy the ModuleRegistry - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_fundsReceiver; - let account_delegate; - let blockNo; - let balanceOfReceiver; - let message = "Transaction Should Fail!"; - const TM_Perm = "WHITELIST"; - const delegateDetails = "I am delegate" - // investor Details - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_CappedSTOFactory; - let I_MRProxied; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_CappedSTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = "Demo Token"; - const symbol = "DET"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // Capped STO details - //let startTime; // Start time will be 5000 seconds more than the latest time - //let endTime; // Add 30 days more - const cap = web3.utils.toWei("10000"); - const rate = 1000; - const fundRaiseType = [0]; - const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); - const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[3]; - account_investor2 = accounts[2]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - token_owner = account_issuer; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + // STEP 4: Deploy the GeneralTransferManagerFactory - // STEP 5: Deploy the GeneralDelegateManagerFactory + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + // STEP 5: Deploy the GeneralDelegateManagerFactory - // STEP 6: Deploy the CappedSTOFactory + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); + // STEP 6: Deploy the CappedSTOFactory - // Step 8: Deploy the STFactory contract + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CappedSTOFactory contract was not deployed' + ); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + // Step 8: Deploy the STFactory contract - // Step 9: Deploy the SecurityTokenRegistry contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + // Step 9: Deploy the SecurityTokenRegistry contract - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // STEP 7: Register the Modules with the ModuleRegistry contract + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // STEP 7: Register the Modules with the ModuleRegistry contract - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -222,202 +219,170 @@ contract('Issuance', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); - }); + }); - describe("Launch SecurityToken & STO on the behalf of the issuer", async() => { + describe('Launch SecurityToken & STO on the behalf of the issuer', async () => { + describe('Create securityToken for the issuer by the polymath', async () => { + it('POLYMATH: Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_polymath); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); + let tx = await I_STRProxied.registerTicker(account_polymath, symbol, name, { from: account_polymath }); + assert.equal(tx.logs[0].args._owner, account_polymath); + assert.equal(tx.logs[0].args._ticker, symbol); + }); - describe("Create securityToken for the issuer by the polymath", async() => { + it('POLYMATH: Should generate the new security token with the same symbol as registered above', async () => { + console.log(name, symbol, tokenDetails, false); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_polymath }); - it("POLYMATH: Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_polymath); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); - let tx = await I_STRProxied.registerTicker(account_polymath, symbol, name, { from : account_polymath }); - assert.equal(tx.logs[0].args._owner, account_polymath); - assert.equal(tx.logs[0].args._ticker, symbol); - }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - it("POLYMATH: Should generate the new security token with the same symbol as registered above", async () => { - console.log(name, symbol, tokenDetails, false); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_polymath }); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + it('POLYMATH: Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); + it('POLYMATH: Should successfully attach the STO factory with the security token', async () => { + // STEP 4: Deploy the CappedSTOFactory - it("POLYMATH: Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: account_polymath }); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CappedSTOFactory contract was not deployed' + ); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + + let bytesSTO = encodeModuleCall(STOParameters, [ + latestTime() + duration.seconds(5000), + latestTime() + duration.days(30), + cap, + rate, + fundRaiseType, + account_fundsReceiver + ]); + + await I_PolyToken.getTokens(cappedSTOSetupCost, account_polymath); + await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: account_polymath }); + + const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: account_polymath }); + + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), + 'CappedSTO', + 'CappedSTOFactory module was not added' + ); + I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); + }); + }); - }); + describe('Transfer Manager operations by the polymath_account', async () => { + it('Should modify the whitelist', async () => { + fromTime = latestTime(); + toTime = latestTime() + duration.days(15); + expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + fromTime + duration.days(70), + toTime + duration.days(90), + expiryTime + duration.days(50), + true, + { + from: account_polymath + } + ); + assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); + }); + + it('Should add the delegate with permission', async () => { + //First attach a permission manager to the token + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '', 0, 0, { from: account_polymath }); + let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); + I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); + // Add permission to the deletgate (A regesteration process) + await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath }); + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { + from: account_polymath + }); - it("POLYMATH: Should successfully attach the STO factory with the security token", async () => { - // STEP 4: Deploy the CappedSTOFactory + assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); + }); - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: account_polymath }); + it('POLYMATH: Should change the ownership of the SecurityToken', async () => { + await I_SecurityToken.transferOwnership(token_owner, { from: account_polymath }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); + assert.equal(await I_SecurityToken.owner.call(), token_owner); + }); + }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + describe('Operations on the STO', async () => { + it('Should Buy the tokens', async () => { + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + blockNo = latestBlock(); + // Jump time + await increaseTime(5000); + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO.address, + gas: 6100000, + value: web3.utils.toWei('1', 'ether') + }); - let bytesSTO = encodeModuleCall(STOParameters, [(latestTime() + duration.seconds(5000)), (latestTime() + duration.days(30)), cap, rate, fundRaiseType, account_fundsReceiver]); + assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - await I_PolyToken.getTokens(cappedSTOSetupCost, account_polymath); - await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: account_polymath}); + assert.equal(await I_CappedSTO.investorCount.call(), 1); - const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: account_polymath }); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "CappedSTO", - "CappedSTOFactory module was not added" - ); - I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); - }); - }); + it('Verification of the event Token Purchase', async () => { + const log = await promisifyLogWatch(I_CappedSTO.TokenPurchase({ from: blockNo }), 1); + assert.equal(log.args.purchaser, account_investor1, 'Wrong address of the investor'); + assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000, 'Wrong No. token get dilivered'); + }); - describe("Transfer Manager operations by the polymath_account", async() => { - it("Should modify the whitelist", async () => { - - fromTime = latestTime(); - toTime = latestTime() + duration.days(15); - expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime + duration.days(70), - toTime + duration.days(90), - expiryTime + duration.days(50), - true, - { - from: account_polymath - }); - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); - }); - - it("Should add the delegate with permission", async() => { - //First attach a permission manager to the token - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: account_polymath}); - let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); - I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath}); - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: account_polymath }); - - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); - }); - - it("POLYMATH: Should change the ownership of the SecurityToken", async() => { - await I_SecurityToken.transferOwnership(token_owner, { from : account_polymath }); - - assert.equal(await I_SecurityToken.owner.call(), token_owner); - }); - }) - - describe("Operations on the STO", async() => { - it("Should Buy the tokens", async() => { - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - blockNo = latestBlock(); - // Jump time - await increaseTime(5000); - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO.address, - gas: 6100000, - value: web3.utils.toWei('1', 'ether') - }); - - assert.equal( - (await I_CappedSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); - - assert.equal(await I_CappedSTO.investorCount.call(), 1); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }); - - it("Verification of the event Token Purchase", async() => { - const log = await promisifyLogWatch(I_CappedSTO.TokenPurchase({from: blockNo}), 1); - assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); - assert.equal( - (log.args.amount) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000, - "Wrong No. token get dilivered" - ); - }); - - it("should add the investor into the whitelist by the delegate", async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - { - from: account_delegate, - gas: 7000000 - }); - assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - }); - - it("Should buy the token", async () => { - await web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); - - assert.equal( - (await I_CappedSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 2 - ); - - assert.equal(await I_CappedSTO.investorCount.call(), 2); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }) + it('should add the investor into the whitelist by the delegate', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { + from: account_delegate, + gas: 7000000 }); + assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); + }); + + it('Should buy the token', async () => { + await web3.eth.sendTransaction({ + from: account_investor2, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }); + + assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2); + + assert.equal(await I_CappedSTO.investorCount.call(), 2); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); }); + }); }); diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index b61c44e67..5d23bca83 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -24,209 +24,217 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('ManualApprovalTransferManager', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_investor5; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_ManualApprovalTransferManagerFactory; + let P_ManualApprovalTransferManagerFactory; + let P_ManualApprovalTransferManager; + let I_CountTransferManagerFactory; + let I_GeneralPermissionManager; + let I_ManualApprovalTransferManager; + let I_CountTransferManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_MRProxied; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_investor5 = accounts[5]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_investor5; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_ManualApprovalTransferManagerFactory; - let P_ManualApprovalTransferManagerFactory; - let P_ManualApprovalTransferManager; - let I_CountTransferManagerFactory; - let I_GeneralPermissionManager; - let I_ManualApprovalTransferManager; - let I_CountTransferManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_MRProxied; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_investor5 = accounts[5]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactoryFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 6: Deploy the ManualApprovalTransferManagerFactory - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_ManualApprovalTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ManualApprovalTransferManagerFactory contract was not deployed" - ); - - // STEP 7: Deploy the Paid ManualApprovalTransferManagerFactory - P_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); - assert.notEqual( - P_ManualApprovalTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ManualApprovalTransferManagerFactory contract was not deployed" - ); - - // STEP 8: Deploy the CountTransferManagerFactory - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_CountTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CountTransferManagerFactory contract was not deployed" - ); - - // Step 10: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 11: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 12: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 13: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 9: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the ManualApprovalTransferManagerFactory - await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the ManualApprovalTransferManagerFactory - await I_MRProxied.registerModule(P_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); - - // (D) : Register the CountTransferManagerFactory - await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); + + // STEP 5: Deploy the GeneralDelegateManagerFactoryFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); + + // STEP 6: Deploy the ManualApprovalTransferManagerFactory + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + assert.notEqual( + I_ManualApprovalTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'ManualApprovalTransferManagerFactory contract was not deployed' + ); + + // STEP 7: Deploy the Paid ManualApprovalTransferManagerFactory + P_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new( + I_PolyToken.address, + web3.utils.toWei('500', 'ether'), + 0, + 0, + { from: account_polymath } + ); + assert.notEqual( + P_ManualApprovalTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'ManualApprovalTransferManagerFactory contract was not deployed' + ); + + // STEP 8: Deploy the CountTransferManagerFactory + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_CountTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CountTransferManagerFactory contract was not deployed' + ); + + // Step 10: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + + // Step 11: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 12: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 13: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // STEP 9: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the ManualApprovalTransferManagerFactory + await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the ManualApprovalTransferManagerFactory + await I_MRProxied.registerModule(P_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); + + // (D) : Register the CountTransferManagerFactory + await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -242,366 +250,389 @@ contract('ManualApprovalTransferManager', accounts => { CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toUtf8(log.args._name), 'GeneralTransferManager'); + }); + + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + }); + + describe('Buy tokens using whitelist & manual approvals', async () => { + it('Should Buy the tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('4', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('4', 'ether')); + }); + + it('Should Buy some more tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Should successfully attach the ManualApprovalTransferManager with the security token', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); + await catchRevert( + I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, '0x', web3.utils.toWei('500', 'ether'), 0, { + from: token_owner + }) + ); + }); + + it('Should successfully attach the General permission manager factory with the security token', async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); + const tx = await I_SecurityToken.addModule( + P_ManualApprovalTransferManagerFactory.address, + '0x', + web3.utils.toWei('500', 'ether'), + 0, + { from: token_owner } + ); + assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), + 'ManualApprovalTransferManager', + 'ManualApprovalTransferManagerFactory module was not added' + ); + P_ManualApprovalTransferManagerFactory = ManualApprovalTransferManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it('Should successfully attach the ManualApprovalTransferManager with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, '', 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toUtf8(tx.logs[2].args._name), + 'ManualApprovalTransferManager', + 'ManualApprovalTransferManager module was not added' + ); + I_ManualApprovalTransferManager = ManualApprovalTransferManager.at(tx.logs[2].args._module); + }); + //function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { + it('Cannot call verifyTransfer on the TM directly if _isTransfer == true', async () => { + await catchRevert( + I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { + from: token_owner + }) + ); + }); + + it('Can call verifyTransfer on the TM directly if _isTransfer == false', async () => { + await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), false, { + from: token_owner + }); + }); + + it('Add a new token holder', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Should still be able to transfer between existing token holders', async () => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('5', 'ether')); + }); + + it('Should fail to add a manual approval because invalid _from address', async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualApproval( + '', + account_investor4, + web3.utils.toWei('2', 'ether'), + latestTime() + duration.days(1), + { from: token_owner } + ) + ); + }); + + it('Should fail to add a manual approval because invalid _to address', async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + '', + web3.utils.toWei('2', 'ether'), + latestTime() + duration.days(1), + { from: token_owner } + ) + ); + }); + + it('Should fail to add a manual approval because invalid expiry time', async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { + from: token_owner + }) + ); + }); + + it('Add a manual approval for a 4th investor', async () => { + await I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + account_investor4, + web3.utils.toWei('2', 'ether'), + latestTime() + duration.days(1), + { from: token_owner } + ); + }); + + it('Should fail to revoke manual approval because invalid _from address', async () => { + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval('', account_investor4, { from: token_owner })); }); - describe("Generate the SecurityToken", async() => { + it('Should fail to revoke manual approval because invalid _to address', async () => { + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, '', { from: token_owner })); + }); + + it('Should revoke manual approval', async () => { + let tx = await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, account_investor4, { from: token_owner }); + assert.equal(tx.logs[0].args._from, account_investor1); + assert.equal(tx.logs[0].args._to, account_investor4); + assert.equal(tx.logs[0].args._addedBy, token_owner); + await I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + account_investor4, + web3.utils.toWei('2', 'ether'), + latestTime() + duration.days(1), + { from: token_owner } + ); + }); + + it('Use 50% of manual approval for transfer', async () => { + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor4)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('Check verifyTransfer without actually transferring', async () => { + let verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); + console.log(JSON.stringify(verified)); + assert.equal(verified, true); + + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('2', 'ether')); + assert.equal(verified, false); + + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); + assert.equal(verified, true); + }); + + it('Use remaining 50% of manual approval for transfer', async () => { + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor4)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + + it('Check further transfers fail', async () => { + await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + + //Check that other transfers are still valid + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + }); + + it('Should fail to add a manual block because invalid _from address', async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualBlocking('', account_investor2, latestTime() + duration.days(1), { from: token_owner }) + ); + }); - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toUtf8(log.args._name), "GeneralTransferManager"); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - }); - - describe("Buy tokens using whitelist & manual approvals", async() => { - - it("Should Buy the tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('4', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('4', 'ether') - ); - }); - - it("Should Buy some more tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { - - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); - }); - - it("Should successfully attach the General permission manager factory with the security token", async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "ManualApprovalTransferManager", - "ManualApprovalTransferManagerFactory module was not added" - ); - P_ManualApprovalTransferManagerFactory = ManualApprovalTransferManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - - it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); - assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManager module was not added"); - I_ManualApprovalTransferManager = ManualApprovalTransferManager.at(tx.logs[2].args._module); - }); -//function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { - it("Cannot call verifyTransfer on the TM directly if _isTransfer == true", async() => { - - await catchRevert(I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { from: token_owner })); - - }); - - it("Can call verifyTransfer on the TM directly if _isTransfer == false", async() => { - await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), false, { from: token_owner }); - }); - - it("Add a new token holder", async() => { - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should still be able to transfer between existing token holders", async() => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('5', 'ether') - ); - }); - - it("Should fail to add a manual approval because invalid _from address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualApproval("", account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); - }); - - it("Should fail to add a manual approval because invalid _to address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, "", web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); - }); - - it("Should fail to add a manual approval because invalid expiry time", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { from: token_owner })); - }); - - it("Add a manual approval for a 4th investor", async() => { - await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); - }); - - it("Should fail to revoke manual approval because invalid _from address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner })); - }); - - it("Should fail to revoke manual approval because invalid _to address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, "", { from: token_owner })); - }); - - it("Should revoke manual approval", async() => { - let tx = await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, account_investor4, { from: token_owner }); - assert.equal(tx.logs[0].args._from, account_investor1); - assert.equal(tx.logs[0].args._to, account_investor4); - assert.equal(tx.logs[0].args._addedBy, token_owner); - await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); - }); - - it("Use 50% of manual approval for transfer", async() => { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor4)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Check verifyTransfer without actually transferring", async() => { - let verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); - console.log(JSON.stringify(verified)); - assert.equal(verified, true); - - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('2', 'ether')); - assert.equal(verified, false); - - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); - assert.equal(verified, true); - - }); - - it("Use remaining 50% of manual approval for transfer", async() => { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor4)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Check further transfers fail", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - - //Check that other transfers are still valid - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - - }); - - it("Should fail to add a manual block because invalid _from address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { from: token_owner })); - }); - - it("Should fail to add a manual block because invalid _to address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { from: token_owner })); - }); - - it("Should fail to add a manual block because invalid expiry time", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner })); - }); - - it("Add a manual block for a 2nd investor", async() => { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); - }); - - it("Check manual block causes failure", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - - }); - - it("Should fail to revoke manual block because invalid _from address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking("0x0", account_investor2, { from: token_owner })); - }); - - it("Should fail to revoke manual block because invalid _to address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, "0x0", { from: token_owner })); - }); - - it("Revoke manual block and check transfer works", async() => { - await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, account_investor2, { from: token_owner }); - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Check manual block ignored after expiry", async() => { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); - - await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - await increaseTime(1 + (24 * 60 * 60)); - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - }); - - it("Should successfully attach the CountTransferManager with the security token (count of 1)", async () => { - let bytesCountTM = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_maxHolderCount' - } - ] - }, [1]); - - const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); - let name = web3.utils.toUtf8(tx.logs[2].args._name); - assert.equal(name, "CountTransferManager", "CountTransferManager module was not added"); - I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); - - }); - - it("Should get the permission list", async() => { - let perm = await I_ManualApprovalTransferManager.getPermissions.call(); - assert.equal(perm.length, 1); - }); - - // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { - // //Should fail initial transfer - // - // try { - // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - // } catch(error) { - // console.log(`Failed due to to count block`); - // ensureException(error); - // errorThrown = true; - // } - // //Add a manual approval - transfer should now work - // await I_ManualApprovalTransferManager.addManualApproval(account_investor2, account_investor5, web3.utils.toWei('1', 'ether'), latestTime() + duration.days(1), { from: token_owner }); - // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - // }); - - it("Should get the init function", async() => { - let byte = await I_ManualApprovalTransferManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); - }); - - }); - - describe("ManualApproval Transfer Manager Factory test cases", async() => { - - it("Should get the exact details of the factory", async() => { - assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_ManualApprovalTransferManagerFactory.getType.call(),2); - let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); - assert.equal(name,"ManualApprovalTransferManager","Wrong Module added"); - let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); - assert.equal(desc,"Manage transfers using single approvals / blocking","Wrong Module added"); - let title = await I_ManualApprovalTransferManagerFactory.getTitle.call(); - assert.equal(title,"Manual Approval Transfer Manager","Wrong Module added"); - let inst = await I_ManualApprovalTransferManagerFactory.getInstructions.call(); - assert.equal(inst,"Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.","Wrong Module added"); - }); - - it("Should get the tags of the factory", async() => { - let tags = await I_ManualApprovalTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toUtf8(tags[0]), "ManualApproval"); - }); + it('Should fail to add a manual block because invalid _to address', async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualBlocking(account_investor1, '', latestTime() + duration.days(1), { from: token_owner }) + ); }); + it('Should fail to add a manual block because invalid expiry time', async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner }) + ); + }); + + it('Add a manual block for a 2nd investor', async () => { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { + from: token_owner + }); + }); + + it('Check manual block causes failure', async () => { + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + }); + + it('Should fail to revoke manual block because invalid _from address', async () => { + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking('0x0', account_investor2, { from: token_owner })); + }); + + it('Should fail to revoke manual block because invalid _to address', async () => { + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, '0x0', { from: token_owner })); + }); + + it('Revoke manual block and check transfer works', async () => { + await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, account_investor2, { from: token_owner }); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + + it('Check manual block ignored after expiry', async () => { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { + from: token_owner + }); + + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + await increaseTime(1 + 24 * 60 * 60); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + }); + + it('Should successfully attach the CountTransferManager with the security token (count of 1)', async () => { + let bytesCountTM = web3.eth.abi.encodeFunctionCall( + { + name: 'configure', + type: 'function', + inputs: [ + { + type: 'uint256', + name: '_maxHolderCount' + } + ] + }, + [1] + ); + + const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); + let name = web3.utils.toUtf8(tx.logs[2].args._name); + assert.equal(name, 'CountTransferManager', 'CountTransferManager module was not added'); + I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); + }); + + it('Should get the permission list', async () => { + let perm = await I_ManualApprovalTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + }); + + // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { + // //Should fail initial transfer + // + // try { + // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + // } catch(error) { + // console.log(`Failed due to to count block`); + // ensureException(error); + // errorThrown = true; + // } + // //Add a manual approval - transfer should now work + // await I_ManualApprovalTransferManager.addManualApproval(account_investor2, account_investor5, web3.utils.toWei('1', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + // }); + + it('Should get the init function', async () => { + let byte = await I_ManualApprovalTransferManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); + }); + }); + + describe('ManualApproval Transfer Manager Factory test cases', async () => { + it('Should get the exact details of the factory', async () => { + assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(), 0); + assert.equal(await I_ManualApprovalTransferManagerFactory.getType.call(), 2); + let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); + assert.equal(name, 'ManualApprovalTransferManager', 'Wrong Module added'); + let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); + assert.equal(desc, 'Manage transfers using single approvals / blocking', 'Wrong Module added'); + let title = await I_ManualApprovalTransferManagerFactory.getTitle.call(); + assert.equal(title, 'Manual Approval Transfer Manager', 'Wrong Module added'); + let inst = await I_ManualApprovalTransferManagerFactory.getInstructions.call(); + assert.equal( + inst, + 'Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.', + 'Wrong Module added' + ); + }); + + it('Should get the tags of the factory', async () => { + let tags = await I_ManualApprovalTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toUtf8(tags[0]), 'ManualApproval'); + }); + }); }); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index b301081c5..43997096f 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); @@ -25,177 +25,172 @@ const TestSTOFactory = artifacts.require('./TestSTOFactory.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('ModuleRegistry', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_fundsReceiver; + let account_delegate; + let account_temp; + + let balanceOfReceiver; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + + let ID_snap; + let message = 'Transaction Should fail!'; + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_CappedSTOFactory1; + let I_CappedSTOFactory2; + let I_STFactory; + let I_MRProxied; + let I_SecurityToken; + let I_STRProxied; + let I_CappedSTO; + let I_PolyToken; + let I_MockFactory; + let I_TestSTOFactory; + let I_DummySTOFactory; + let I_PolymathRegistry; + let I_SecurityToken2; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = 'Demo Token'; + const symbol = 'det'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // delagate details + const delegateDetails = 'I am delegate ..'; + const TM_Perm = 'FLAGS'; + + // Capped STO details + let startTime; + let endTime; + const cap = web3.utils.toWei('10000'); + const rate = 1000; + const fundRaiseType = [0]; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[9]; + account_investor2 = accounts[6]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + account_temp = accounts[8]; + token_owner = account_issuer; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_fundsReceiver; - let account_delegate; - let account_temp; - - let balanceOfReceiver; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - - let ID_snap; - let message = "Transaction Should fail!"; - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_CappedSTOFactory1; - let I_CappedSTOFactory2; - let I_STFactory; - let I_MRProxied; - let I_SecurityToken; - let I_STRProxied; - let I_CappedSTO; - let I_PolyToken; - let I_MockFactory; - let I_TestSTOFactory; - let I_DummySTOFactory; - let I_PolymathRegistry; - let I_SecurityToken2; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = "Demo Token"; - const symbol = "det"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // delagate details - const delegateDetails = "I am delegate .."; - const TM_Perm = 'FLAGS'; - - // Capped STO details - let startTime; - let endTime; - const cap = web3.utils.toWei("10000"); - const rate = 1000; - const fundRaiseType = [0]; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256','uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[9]; - account_investor2 = accounts[6]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - account_temp = accounts[8]; - token_owner = account_issuer; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - - assert.notEqual( - I_ModuleRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ModuleRegistry contract was not deployed", - ); - - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - let tx = await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - - - assert.notEqual( - I_FeatureRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "FeatureRegistry contract was not deployed", - ); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // Printing all the contract addresses - console.log(` + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + + assert.notEqual( + I_ModuleRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'ModuleRegistry contract was not deployed' + ); + + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + let tx = await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + + // Step 9: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 10: update the registries addresses from the PolymathRegistry contract + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'FeatureRegistry contract was not deployed' + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -208,380 +203,350 @@ contract('ModuleRegistry', accounts => { GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Test cases for the ModuleRegistry', async () => { + describe('Test case for the upgradeFromregistry', async () => { + it('Should successfully update the registry contract address -- failed because of bad owner', async () => { + await catchRevert(I_MRProxied.updateFromRegistry({ from: account_temp })); + }); + + it('Should successfully update the registry contract addresses', async () => { + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + assert.equal( + await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('securityTokenRegistry')), + I_SecurityTokenRegistryProxy.address + ); + assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('featureRegistry')), I_FeatureRegistry.address); + assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('polyToken')), I_PolyToken.address); + }); }); - describe("Test cases for the ModuleRegistry", async() => { + describe('Test the state variables', async () => { + it('Should be the right owner', async () => { + let _owner = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')); + assert.equal(_owner, account_polymath, 'Owner should be the correct'); + }); - describe("Test case for the upgradeFromregistry", async() => { + it('Should be the expected value of the paused and intialised variable', async () => { + let _paused = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); + assert.isFalse(_paused, 'Should be the false'); - it("Should successfully update the registry contract address -- failed because of bad owner", async() => { - - await catchRevert(I_MRProxied.updateFromRegistry({from: account_temp})); - }); + let _intialised = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('initialised')); + assert.isTrue(_intialised, 'Values should be the true'); + }); - it("Should successfully update the registry contract addresses", async() => { - await I_MRProxied.updateFromRegistry({from: account_polymath}); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("securityTokenRegistry")), I_SecurityTokenRegistryProxy.address); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("featureRegistry")), I_FeatureRegistry.address); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")), I_PolyToken.address); - }); + it('Should be the expected value of the polymath registry', async () => { + let _polymathRegistry = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('polymathRegistry')); + assert.equal(_polymathRegistry, I_PolymathRegistry.address, 'Should be the right value of the address of the polymath registry'); + }); + }); - }); + describe('Test cases for the registering the module', async () => { + it('Should fail to register the module -- when registerModule is paused', async () => { + await I_MRProxied.pause({ from: account_polymath }); - describe("Test the state variables", async() => { + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_delegate })); + await I_MRProxied.unpause({ from: account_polymath }); + }); - it("Should be the right owner", async() => { - let _owner = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')); - assert.equal(_owner, account_polymath, "Owner should be the correct"); - }) + it('Should register the module with the Module Registry', async () => { + let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, 'Should be the same address'); + assert.equal(tx.logs[0].args._owner, account_polymath, 'Should be the right owner'); - it("Should be the expected value of the paused and intialised variable", async() => { - let _paused = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); - assert.isFalse(_paused, "Should be the false"); + let _list = await I_MRProxied.getModulesByType(transferManagerKey); + assert.equal(_list.length, 1, 'Length should be 1'); + assert.equal(_list[0], I_GeneralTransferManagerFactory.address); - let _intialised = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("initialised")); - assert.isTrue(_intialised, "Values should be the true"); - }) + let _reputation = await I_MRProxied.getReputationByFactory(I_GeneralTransferManagerFactory.address); + assert.equal(_reputation.length, 0); + }); - it("Should be the expected value of the polymath registry", async() => { - let _polymathRegistry = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry")); - assert.equal(_polymathRegistry, I_PolymathRegistry.address, "Should be the right value of the address of the polymath registry"); - }); - }); + it('Should fail the register the module -- Already registered module', async () => { + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath })); + }); - describe("Test cases for the registering the module", async() => { - - it("Should fail to register the module -- when registerModule is paused", async() => { - await I_MRProxied.pause({from: account_polymath}); - - await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_delegate})); - await I_MRProxied.unpause({from: account_polymath}); - }) - - it("Should register the module with the Module Registry", async() => { - let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath}); - assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, "Should be the same address"); - assert.equal(tx.logs[0].args._owner, account_polymath, "Should be the right owner"); - - let _list = await I_MRProxied.getModulesByType(transferManagerKey); - assert.equal(_list.length, 1, "Length should be 1"); - assert.equal(_list[0], I_GeneralTransferManagerFactory.address); - - let _reputation = await I_MRProxied.getReputationByFactory(I_GeneralTransferManagerFactory.address); - assert.equal(_reputation.length, 0); - }); - - it("Should fail the register the module -- Already registered module", async() => { - - await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath})); - }) - - it("Should fail in registering the module-- type = 0", async() => { - I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - - await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); - }); - }); + it('Should fail in registering the module-- type = 0', async () => { + I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - describe("Test case for verifyModule", async() => { - - it("Should fail in calling the verify module. Because msg.sender should be account_polymath", async () => { - - await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); - }); - - it("Should successfully verify the module -- true", async() => { - let tx = await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - assert.equal( - tx.logs[0].args._moduleFactory, - I_GeneralTransferManagerFactory.address, - "Failed in verifying the module" - ); - assert.equal( - tx.logs[0].args._verified, - true, - "Failed in verifying the module" - ); - }); - - it("Should successfully verify the module -- false", async() => { - I_CappedSTOFactory1 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - await I_MRProxied.registerModule(I_CappedSTOFactory1.address, {from: account_polymath}); - let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory1.address, false, { from: account_polymath }); - assert.equal( - tx.logs[0].args._moduleFactory, - I_CappedSTOFactory1.address, - "Failed in verifying the module" - ); - assert.equal( - tx.logs[0].args._verified, - false, - "Failed in verifying the module" - ); - }); - - it("Should fail in verifying the module. Because the module is not registered", async() => { - - await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); - }); - }) - - describe("Test cases for the useModule function of the module registry", async() => { - - it("Deploy the securityToken", async() => { - await I_PolyToken.getTokens(web3.utils.toWei("500"), account_issuer); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), {from: account_issuer}); - await I_STRProxied.registerTicker(account_issuer, symbol, name, {from: account_issuer}); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, {from: account_issuer}); - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase()); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - }); - - it("Should fail in adding module. Because module is un-verified", async() => { - startTime = latestTime() + duration.seconds(5000); - endTime = startTime + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner})); - }); - - it("Should fail to register module because custom modules not allowed", async() => { - I_CappedSTOFactory2 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); - - assert.notEqual( - I_CappedSTOFactory2.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); - - - - await catchRevert(I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner })); - - }); - - it("Should switch customModulesAllowed to true", async() => { - assert.equal(false, await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), "Custom modules should be dissabled by default."); - let tx = await I_FeatureRegistry.setFeatureStatus("customModulesAllowed", true, { from: account_polymath }); - assert.equal(true, await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), "Custom modules should be switched to true."); - }); - - it("Should successfully add module because custom modules switched on", async() => { - startTime = latestTime() + duration.seconds(5000); - endTime = startTime + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); - tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner}); - - assert.equal(tx.logs[2].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "CappedSTO", - "CappedSTOFactory module was not added" - ); - let _reputation = await I_MRProxied.getReputationByFactory.call(I_CappedSTOFactory2.address); - assert.equal(_reputation.length, 1); - }); - - it("Should successfully add verified module", async() => { - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, {from: account_polymath}); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, {from: account_polymath}); - let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type, permissionManagerKey, "module doesn't get deployed"); - }); - - it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower", async() => { - I_TestSTOFactory = await TestSTOFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - await I_MRProxied.registerModule(I_TestSTOFactory.address, {from: account_polymath}); - await I_MRProxied.verifyModule(I_TestSTOFactory.address, true, {from: account_polymath}); - // Taking the snapshot the revert the changes from here - let id = await takeSnapshot(); - await I_TestSTOFactory.changeSTVersionBounds("lowerBound", [0,1,0], {from: account_polymath}); - let _lstVersion = await I_TestSTOFactory.getLowerSTVersionBounds.call() - assert.equal(_lstVersion[2],0); - assert.equal(_lstVersion[1],1); - let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); - - await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); - await revertToSnapshot(id); - }) - - it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --upper", async() => { - await I_TestSTOFactory.changeSTVersionBounds("upperBound", [0,0,1], {from: account_polymath}); - let _ustVersion = await I_TestSTOFactory.getUpperSTVersionBounds.call() - assert.equal(_ustVersion[0],0); - assert.equal(_ustVersion[2],1); - await I_STRProxied.setProtocolVersion(I_STFactory.address, 1, 0, 1); - - // Generate the new securityToken - let newSymbol = "toro"; - await I_PolyToken.getTokens(web3.utils.toWei("500"), account_issuer); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), {from: account_issuer}); - await I_STRProxied.registerTicker(account_issuer, newSymbol, name, {from: account_issuer}); - let tx = await I_STRProxied.generateSecurityToken(name, newSymbol, tokenDetails, true, {from: account_issuer}); - assert.equal(tx.logs[1].args._ticker, newSymbol.toUpperCase()); - I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - - let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); - - await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); - }); + await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); + }); + }); - }); + describe('Test case for verifyModule', async () => { + it('Should fail in calling the verify module. Because msg.sender should be account_polymath', async () => { + await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); + }); + + it('Should successfully verify the module -- true', async () => { + let tx = await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, 'Failed in verifying the module'); + assert.equal(tx.logs[0].args._verified, true, 'Failed in verifying the module'); + }); + + it('Should successfully verify the module -- false', async () => { + I_CappedSTOFactory1 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + await I_MRProxied.registerModule(I_CappedSTOFactory1.address, { from: account_polymath }); + let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory1.address, false, { from: account_polymath }); + assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory1.address, 'Failed in verifying the module'); + assert.equal(tx.logs[0].args._verified, false, 'Failed in verifying the module'); + }); + + it('Should fail in verifying the module. Because the module is not registered', async () => { + await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); + }); + }); - describe("Test case for the getModulesByTypeAndToken()", async() => { - - it("Should get the list of available modules when the customModulesAllowed", async() => { - let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); - assert.equal(_list[0], I_CappedSTOFactory2.address); - }) - - it("Should get the list of available modules when the customModulesAllowed is not allowed", async() => { - await I_FeatureRegistry.setFeatureStatus("customModulesAllowed", false, { from: account_polymath }); - let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); - assert.equal(_list.length, 0); - }) - }) - - describe("Test cases for getters", async() => { - - it("Check getter - ", async() => { - console.log("getModulesByType:") - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getModulesByType.call(i); - console.log("Type: " + i + ":" + _list); - } - console.log("getModulesByTypeAndToken:") - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getModulesByTypeAndToken.call(i, I_SecurityToken.address); - console.log("Type: " + i + ":" + _list); - } - console.log("getTagsByType:") - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getTagsByType.call(i); - console.log("Type: " + i + ":" + _list[1]); - console.log("Type: " + i + ":" + _list[0].map(x => web3.utils.toAscii(x))); - } - console.log("getTagsByTypeAndToken:") - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getTagsByTypeAndToken.call(i, I_SecurityToken.address); - console.log("Type: " + i + ":" + _list[1]); - console.log("Type: " + i + ":" + _list[0].map(x => web3.utils.toAscii(x))); - } - }) + describe('Test cases for the useModule function of the module registry', async () => { + it('Deploy the securityToken', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('500'), account_issuer); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: account_issuer }); + await I_STRProxied.registerTicker(account_issuer, symbol, name, { from: account_issuer }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, { from: account_issuer }); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase()); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + }); - }); + it('Should fail in adding module. Because module is un-verified', async () => { + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - describe("Test cases for removeModule()", async() => { + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner })); + }); - it("Should fail if msg.sender not curator or owner", async() => { - - await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp })); - }); + it('Should fail to register module because custom modules not allowed', async () => { + I_CappedSTOFactory2 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); - it("Should successfully remove module and delete data if msg.sender is curator", async() => { - let snap = await takeSnapshot(); + assert.notEqual( + I_CappedSTOFactory2.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CappedSTOFactory contract was not deployed' + ); + + await catchRevert(I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner })); + }); + + it('Should switch customModulesAllowed to true', async () => { + assert.equal( + false, + await I_FeatureRegistry.getFeatureStatus.call('customModulesAllowed'), + 'Custom modules should be dissabled by default.' + ); + let tx = await I_FeatureRegistry.setFeatureStatus('customModulesAllowed', true, { from: account_polymath }); + assert.equal( + true, + await I_FeatureRegistry.getFeatureStatus.call('customModulesAllowed'), + 'Custom modules should be switched to true.' + ); + }); + + it('Should successfully add module because custom modules switched on', async () => { + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); + tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner }); + + assert.equal(tx.logs[2].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'CappedSTO', + 'CappedSTOFactory module was not added' + ); + let _reputation = await I_MRProxied.getReputationByFactory.call(I_CappedSTOFactory2.address); + assert.equal(_reputation.length, 1); + }); - let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; - let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; + it('Should successfully add verified module', async () => { + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '', 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type, permissionManagerKey, "module doesn't get deployed"); + }); + + it('Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower', async () => { + I_TestSTOFactory = await TestSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + await I_MRProxied.registerModule(I_TestSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_TestSTOFactory.address, true, { from: account_polymath }); + // Taking the snapshot the revert the changes from here + let id = await takeSnapshot(); + await I_TestSTOFactory.changeSTVersionBounds('lowerBound', [0, 1, 0], { from: account_polymath }); + let _lstVersion = await I_TestSTOFactory.getLowerSTVersionBounds.call(); + assert.equal(_lstVersion[2], 0); + assert.equal(_lstVersion[1], 1); + let bytesData = encodeModuleCall( + ['uint256', 'uint256', 'uint256', 'string'], + [latestTime(), latestTime() + duration.days(1), cap, 'Test STO'] + ); - assert.equal(sto1,I_CappedSTOFactory1.address); - assert.equal(sto2,I_CappedSTOFactory2.address); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); + await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); + await revertToSnapshot(id); + }); + + it('Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --upper', async () => { + await I_TestSTOFactory.changeSTVersionBounds('upperBound', [0, 0, 1], { from: account_polymath }); + let _ustVersion = await I_TestSTOFactory.getUpperSTVersionBounds.call(); + assert.equal(_ustVersion[0], 0); + assert.equal(_ustVersion[2], 1); + await I_STRProxied.setProtocolVersion(I_STFactory.address, 1, 0, 1); + + // Generate the new securityToken + let newSymbol = 'toro'; + await I_PolyToken.getTokens(web3.utils.toWei('500'), account_issuer); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: account_issuer }); + await I_STRProxied.registerTicker(account_issuer, newSymbol, name, { from: account_issuer }); + let tx = await I_STRProxied.generateSecurityToken(name, newSymbol, tokenDetails, true, { from: account_issuer }); + assert.equal(tx.logs[1].args._ticker, newSymbol.toUpperCase()); + I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + let bytesData = encodeModuleCall( + ['uint256', 'uint256', 'uint256', 'string'], + [latestTime(), latestTime() + duration.days(1), cap, 'Test STO'] + ); - let tx = await I_MRProxied.removeModule(sto1, { from: account_polymath }); + await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); + }); + }); - assert.equal(tx.logs[0].args._moduleFactory, sto1, "Event is not properly emitted for _moduleFactory"); - assert.equal(tx.logs[0].args._decisionMaker, account_polymath, "Event is not properly emitted for _decisionMaker"); + describe('Test case for the getModulesByTypeAndToken()', async () => { + it('Should get the list of available modules when the customModulesAllowed', async () => { + let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); + assert.equal(_list[0], I_CappedSTOFactory2.address); + }); + + it('Should get the list of available modules when the customModulesAllowed is not allowed', async () => { + await I_FeatureRegistry.setFeatureStatus('customModulesAllowed', false, { from: account_polymath }); + let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); + assert.equal(_list.length, 0); + }); + }); - let sto2_end = (await I_MRProxied.getModulesByType.call(3))[1]; + describe('Test cases for getters', async () => { + it('Check getter - ', async () => { + console.log('getModulesByType:'); + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getModulesByType.call(i); + console.log('Type: ' + i + ':' + _list); + } + console.log('getModulesByTypeAndToken:'); + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getModulesByTypeAndToken.call(i, I_SecurityToken.address); + console.log('Type: ' + i + ':' + _list); + } + console.log('getTagsByType:'); + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getTagsByType.call(i); + console.log('Type: ' + i + ':' + _list[1]); + console.log('Type: ' + i + ':' + _list[0].map(x => web3.utils.toAscii(x))); + } + console.log('getTagsByTypeAndToken:'); + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getTagsByTypeAndToken.call(i, I_SecurityToken.address); + console.log('Type: ' + i + ':' + _list[1]); + console.log('Type: ' + i + ':' + _list[0].map(x => web3.utils.toAscii(x))); + } + }); + }); - // re-ordering - assert.equal(sto2_end,sto2); - // delete related data - assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto1)), 0); - assert.equal(await I_MRProxied.getReputationByFactory.call(sto1), 0); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); - assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto1)), false); + describe('Test cases for removeModule()', async () => { + it('Should fail if msg.sender not curator or owner', async () => { + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp })); + }); - await revertToSnapshot(snap); - }); + it('Should successfully remove module and delete data if msg.sender is curator', async () => { + let snap = await takeSnapshot(); - it("Should successfully remove module and delete data if msg.sender is owner", async() => { - let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; - let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; + let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; + let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; - assert.equal(sto1,I_CappedSTOFactory1.address); - assert.equal(sto2,I_CappedSTOFactory2.address); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); + assert.equal(sto1, I_CappedSTOFactory1.address); + assert.equal(sto2, I_CappedSTOFactory2.address); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); - let tx = await I_MRProxied.removeModule(sto2, { from: token_owner }); + let tx = await I_MRProxied.removeModule(sto1, { from: account_polymath }); - assert.equal(tx.logs[0].args._moduleFactory, sto2, "Event is not properly emitted for _moduleFactory"); - assert.equal(tx.logs[0].args._decisionMaker, token_owner, "Event is not properly emitted for _decisionMaker"); + assert.equal(tx.logs[0].args._moduleFactory, sto1, 'Event is not properly emitted for _moduleFactory'); + assert.equal(tx.logs[0].args._decisionMaker, account_polymath, 'Event is not properly emitted for _decisionMaker'); - let sto1_end = (await I_MRProxied.getModulesByType.call(3))[0]; + let sto2_end = (await I_MRProxied.getModulesByType.call(3))[1]; - // re-ordering - assert.equal(sto1_end,sto1); - // delete related data - assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto2)), 0); - assert.equal(await I_MRProxied.getReputationByFactory.call(sto2), 0); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); - assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto2)), false); - }); + // re-ordering + assert.equal(sto2_end, sto2); + // delete related data + assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3('registry', sto1)), 0); + assert.equal(await I_MRProxied.getReputationByFactory.call(sto1), 0); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); + assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('verified', sto1)), false); - it("Should fail if module already removed", async() => { - - await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath })); - }); + await revertToSnapshot(snap); + }); - }); + it('Should successfully remove module and delete data if msg.sender is owner', async () => { + let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; + let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; - describe("Test cases for IRegistry functionality", async() => { + assert.equal(sto1, I_CappedSTOFactory1.address); + assert.equal(sto2, I_CappedSTOFactory2.address); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); - describe("Test cases for reclaiming funds", async() => { + let tx = await I_MRProxied.removeModule(sto2, { from: token_owner }); - it("Should successfully reclaim POLY tokens", async() => { - await I_PolyToken.getTokens(web3.utils.toWei("1"), I_MRProxied.address); - let bal1 = await I_PolyToken.balanceOf.call(account_polymath); - await I_MRProxied.reclaimERC20(I_PolyToken.address); - let bal2 = await I_PolyToken.balanceOf.call(account_polymath); - assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); - }); + assert.equal(tx.logs[0].args._moduleFactory, sto2, 'Event is not properly emitted for _moduleFactory'); + assert.equal(tx.logs[0].args._decisionMaker, token_owner, 'Event is not properly emitted for _decisionMaker'); - }); + let sto1_end = (await I_MRProxied.getModulesByType.call(3))[0]; - describe("Test cases for pausing the contract", async() => { + // re-ordering + assert.equal(sto1_end, sto1); + // delete related data + assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3('registry', sto2)), 0); + assert.equal(await I_MRProxied.getReputationByFactory.call(sto2), 0); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); + assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('verified', sto2)), false); + }); - it("Should fail to pause if msg.sender is not owner", async() => { - - await catchRevert(I_MRProxied.pause({ from: account_temp })); - }); + it('Should fail if module already removed', async () => { + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath })); + }); + }); - it("Should successfully pause the contract", async() => { - await I_MRProxied.pause({ from: account_polymath }); - let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); - assert.isOk(status); - }); + describe('Test cases for IRegistry functionality', async () => { + describe('Test cases for reclaiming funds', async () => { + it('Should successfully reclaim POLY tokens', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('1'), I_MRProxied.address); + let bal1 = await I_PolyToken.balanceOf.call(account_polymath); + await I_MRProxied.reclaimERC20(I_PolyToken.address); + let bal2 = await I_PolyToken.balanceOf.call(account_polymath); + assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); + }); + }); - it("Should fail to unpause if msg.sender is not owner", async() => { - - await catchRevert(I_MRProxied.unpause({ from: account_temp })); - }); + describe('Test cases for pausing the contract', async () => { + it('Should fail to pause if msg.sender is not owner', async () => { + await catchRevert(I_MRProxied.pause({ from: account_temp })); + }); - it("Should successfully unpause the contract", async() => { - await I_MRProxied.unpause({ from: account_polymath }); - let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); - assert.isNotOk(status); - }); + it('Should successfully pause the contract', async () => { + await I_MRProxied.pause({ from: account_polymath }); + let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); + assert.isOk(status); + }); + it('Should fail to unpause if msg.sender is not owner', async () => { + await catchRevert(I_MRProxied.unpause({ from: account_temp })); }); + it('Should successfully unpause the contract', async () => { + await I_MRProxied.unpause({ from: account_polymath }); + let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); + assert.isNotOk(status); + }); + }); }); - }); - + }); }); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 76c623b03..0e34f0f29 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -13,378 +13,383 @@ const SecurityToken = artifacts.require('./SecurityToken.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('PercentageTransferManager', accounts => { - - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let P_PercentageTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let P_PercentageTransferManager; - let I_GeneralTransferManagerFactory; - let I_PercentageTransferManagerFactory; - let I_GeneralPermissionManager; - let I_PercentageTransferManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STRProxied; - let I_MRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - var I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // PercentageTransferManager details - const holderPercentage = 70 * 10**16; // Maximum number of token holders - - let bytesSTO = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_maxHolderPercentage' + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let P_PercentageTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let P_PercentageTransferManager; + let I_GeneralTransferManagerFactory; + let I_PercentageTransferManagerFactory; + let I_GeneralPermissionManager; + let I_PercentageTransferManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_MRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + var I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // PercentageTransferManager details + const holderPercentage = 70 * 10 ** 16; // Maximum number of token holders + + let bytesSTO = web3.eth.abi.encodeFunctionCall( + { + name: 'configure', + type: 'function', + inputs: [ + { + type: 'uint256', + name: '_maxHolderPercentage' } - ] - }, [holderPercentage]); + ] + }, + [holderPercentage] + ); + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[7]; + account_investor2 = accounts[8]; + account_investor3 = accounts[9]; + + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 4(b): Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); + + // STEP 4(c): Deploy the PercentageTransferManager + I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + assert.notEqual( + I_PercentageTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'PercentageTransferManagerFactory contract was not deployed' + ); + + // STEP 4(d): Deploy the PercentageTransferManager + P_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new( + I_PolyToken.address, + web3.utils.toWei('500', 'ether'), + 0, + 0, + { from: account_polymath } + ); + assert.notEqual( + P_PercentageTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'PercentageTransferManagerFactory contract was not deployed' + ); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the PercentageTransferManagerFactory + await I_MRProxied.registerModule(I_PercentageTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_PercentageTransferManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the Paid PercentageTransferManagerFactory + await I_MRProxied.registerModule(P_PercentageTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_PercentageTransferManagerFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - token_owner = account_issuer; + PercentageTransferManagerFactory: ${I_PercentageTransferManagerFactory.address} + ----------------------------------------------------------------------------- + `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); - account_investor1 = accounts[7]; - account_investor2 = accounts[8]; - account_investor3 = accounts[9]; + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - let instances = await setUpPolymathNetwork(account_polymath, token_owner); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - // STEP 4(b): Deploy the GeneralDelegateManagerFactory + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + }); + + describe('Buy tokens using on-chain whitelist', async () => { + it('Should Buy the tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + } + ); - // STEP 4(c): Deploy the PercentageTransferManager - I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_PercentageTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PercentageTransferManagerFactory contract was not deployed" - ); + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - // STEP 4(d): Deploy the PercentageTransferManager - P_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); - assert.notEqual( - P_PercentageTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PercentageTransferManagerFactory contract was not deployed" - ); + // Jump time + await increaseTime(5000); + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); + }); - // (C) : Register the PercentageTransferManagerFactory - await I_MRProxied.registerModule(I_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PercentageTransferManagerFactory.address, true, { from: account_polymath }); + it('Should Buy some more tokens', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + } + ); - // (C) : Register the Paid PercentageTransferManagerFactory - await I_MRProxied.registerModule(P_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_PercentageTransferManagerFactory.address, true, { from: account_polymath }); + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - // Printing all the contract addresses - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} - FeatureRegistry: ${I_FeatureRegistry.address} + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('1', 'ether')); + }); - PercentageTransferManagerFactory: ${I_PercentageTransferManagerFactory.address} - ----------------------------------------------------------------------------- - `); + it('Should successfully attach the PercentageTransferManagerr factory with the security token', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); + await catchRevert( + I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei('500', 'ether'), 0, { + from: token_owner + }) + ); }); - describe("Generate the SecurityToken", async() => { + it('Should successfully attach the PercentageTransferManager factory with the security token', async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); + const tx = await I_SecurityToken.addModule( + P_PercentageTransferManagerFactory.address, + bytesSTO, + web3.utils.toWei('500', 'ether'), + 0, + { from: token_owner } + ); + assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), + 'PercentageTransferManager', + 'PercentageTransferManagerFactory module was not added' + ); + P_PercentageTransferManager = PercentageTransferManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); + it('Should successfully attach the PercentageTransferManager with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'PercentageTransferManager', + 'PercentageTransferManager module was not added' + ); + I_PercentageTransferManager = PercentageTransferManager.at(tx.logs[2].args._module); + }); - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + it('Add a new token holder', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + } + ); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('1', 'ether')); + }); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); + it('Should pause the tranfers at transferManager level', async () => { + let tx = await I_PercentageTransferManager.pause({ from: token_owner }); + }); - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + it('Should still be able to transfer between existing token holders up to limit', async () => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - }); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + it('Should unpause the tranfers at transferManager level', async () => { + await I_PercentageTransferManager.unpause({ from: token_owner }); }); - describe("Buy tokens using on-chain whitelist", async() => { - - it("Should Buy the tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should Buy some more tokens", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should successfully attach the PercentageTransferManagerr factory with the security token", async () => { - - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); - }); - - it("Should successfully attach the PercentageTransferManager factory with the security token", async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "PercentageTransferManager", - "PercentageTransferManagerFactory module was not added" - ); - P_PercentageTransferManager = PercentageTransferManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it("Should successfully attach the PercentageTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "PercentageTransferManager", - "PercentageTransferManager module was not added" - ); - I_PercentageTransferManager = PercentageTransferManager.at(tx.logs[2].args._module); - }); - - it("Add a new token holder", async() => { - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Should pause the tranfers at transferManager level", async() => { - let tx = await I_PercentageTransferManager.pause({from: token_owner}); - }); - - it("Should still be able to transfer between existing token holders up to limit", async() => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Should unpause the tranfers at transferManager level", async() => { - await I_PercentageTransferManager.unpause({from: token_owner}); - }) + it('Should not be able to transfer between existing token holders over limit', async () => { + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 })); + }); - it("Should not be able to transfer between existing token holders over limit", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 })); - }); - - it("Modify holder percentage to 100", async() => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_PercentageTransferManager.changeHolderPercentage(100 * 10**16, { from: token_owner }); - - assert.equal( - (await I_PercentageTransferManager.maxHolderPercentage()).toNumber(), - 100 * 10**16 - ); - }); - - it("Should be able to transfer between existing token holders up to limit", async() => { - await I_PercentageTransferManager.modifyWhitelist(account_investor3, false, { from: token_owner }); - await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); - }); - - it("Should be able to whitelist address and then transfer regardless of holders", async() => { - await I_PercentageTransferManager.changeHolderPercentage(30 * 10**16, { from: token_owner }); - await I_PercentageTransferManager.modifyWhitelist(account_investor1, true, { from: token_owner }); - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor3 }); - }); - - it("Should get the permission", async() => { - let perm = await I_PercentageTransferManager.getPermissions.call(); - assert.equal(perm.length, 1); - }); + it('Modify holder percentage to 100', async () => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_PercentageTransferManager.changeHolderPercentage(100 * 10 ** 16, { from: token_owner }); + assert.equal((await I_PercentageTransferManager.maxHolderPercentage()).toNumber(), 100 * 10 ** 16); }); - describe("Percentage Transfer Manager Factory test cases", async() => { - - it("Should get the exact details of the factory", async() => { - assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(),0); - assert.equal(await I_PercentageTransferManagerFactory.getType.call(),2); - assert.equal(web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "PercentageTransferManager", - "Wrong Module added"); - assert.equal(await I_PercentageTransferManagerFactory.getDescription.call(), - "Restrict the number of investors", - "Wrong Module added"); - assert.equal(await I_PercentageTransferManagerFactory.getTitle.call(), - "Percentage Transfer Manager", - "Wrong Module added"); - assert.equal(await I_PercentageTransferManagerFactory.getInstructions.call(), - "Allows an issuer to restrict the total number of non-zero token holders", - "Wrong Module added"); - - }); - - it("Should get the tags of the factory", async() => { - let tags = await I_PercentageTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "Percentage"); - }); + it('Should be able to transfer between existing token holders up to limit', async () => { + await I_PercentageTransferManager.modifyWhitelist(account_investor3, false, { from: token_owner }); + await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); }); + it('Should be able to whitelist address and then transfer regardless of holders', async () => { + await I_PercentageTransferManager.changeHolderPercentage(30 * 10 ** 16, { from: token_owner }); + await I_PercentageTransferManager.modifyWhitelist(account_investor1, true, { from: token_owner }); + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor3 }); + }); + + it('Should get the permission', async () => { + let perm = await I_PercentageTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + }); + }); + + describe('Percentage Transfer Manager Factory test cases', async () => { + it('Should get the exact details of the factory', async () => { + assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(), 0); + assert.equal(await I_PercentageTransferManagerFactory.getType.call(), 2); + assert.equal( + web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()).replace(/\u0000/g, ''), + 'PercentageTransferManager', + 'Wrong Module added' + ); + assert.equal( + await I_PercentageTransferManagerFactory.getDescription.call(), + 'Restrict the number of investors', + 'Wrong Module added' + ); + assert.equal(await I_PercentageTransferManagerFactory.getTitle.call(), 'Percentage Transfer Manager', 'Wrong Module added'); + assert.equal( + await I_PercentageTransferManagerFactory.getInstructions.call(), + 'Allows an issuer to restrict the total number of non-zero token holders', + 'Wrong Module added' + ); + }); + + it('Should get the tags of the factory', async () => { + let tags = await I_PercentageTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Percentage'); + }); + }); }); diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index edda686f3..7e03917e6 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const PreSaleSTOFactory = artifacts.require('./PreSaleSTOFactory.sol'); const PreSaleSTO = artifacts.require('./PreSaleSTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -22,184 +22,184 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('PreSaleSTO', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_investor3; - let account_fundsReceiver; - - let balanceOfReceiver; - let message = "Transaction Should Fail!"; - // investor Details - let fromTime; - let toTime; - let expiryTime; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_PreSaleSTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_MRProxied; - let I_STRProxied; - let I_PreSaleSTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details for funds raise Type ETH - const name = "Team"; - const symbol = "SAP"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - - // SecurityToken Details for funds raise Type POLY - const P_name = "Team Poly"; - const P_symbol = "PAS"; - const P_tokenDetails = "This is equity type of issuance"; - const P_decimals = 18; - - // Module key - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - let endTime; - const STOParameters = ['uint256']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[4]; - account_investor2 = accounts[3]; - account_investor3 = accounts[5]; - account_fundsReceiver = accounts[2]; - token_owner = account_issuer; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the PreSaleSTOFactory - - I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); - - assert.notEqual( - I_PreSaleSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PreSaleSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 9: Deploy the SecurityTokenRegistry contract + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_investor3; + let account_fundsReceiver; + + let balanceOfReceiver; + let message = 'Transaction Should Fail!'; + // investor Details + let fromTime; + let toTime; + let expiryTime; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_PreSaleSTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_MRProxied; + let I_STRProxied; + let I_PreSaleSTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details for funds raise Type ETH + const name = 'Team'; + const symbol = 'SAP'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + // SecurityToken Details for funds raise Type POLY + const P_name = 'Team Poly'; + const P_symbol = 'PAS'; + const P_tokenDetails = 'This is equity type of issuance'; + const P_decimals = 18; + + // Module key + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + let endTime; + const STOParameters = ['uint256']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[4]; + account_investor2 = accounts[3]; + account_investor3 = accounts[5]; + account_fundsReceiver = accounts[2]; + token_owner = account_issuer; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); + + // STEP 3: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); + + // STEP 4: Deploy the PreSaleSTOFactory - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_PreSaleSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'PreSaleSTOFactory contract was not deployed' + ); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 8: Deploy the STFactory contract - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - // STEP 5: Register the Modules with the ModuleRegistry contract + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // Step 9: Deploy the SecurityTokenRegistry contract - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // Printing all the contract addresses - console.log(` + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -216,227 +216,202 @@ contract('PreSaleSTO', accounts => { LatestTime: ${latestTime()}\n ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it("Should fail to launch the STO due to endTime is 0", async () => { - let bytesSTO = encodeModuleCall(STOParameters, [0]); - - await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); - }); - - it("Should successfully attach the STO factory with the security token", async () => { - endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time - let bytesSTO = encodeModuleCall(STOParameters, [endTime]); - - const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); - - assert.equal(tx.logs[2].args._type, stoKey, "PreSaleSTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "PreSaleSTO", - "PreSaleSTOFactory module was not added" - ); - I_PreSaleSTO = PreSaleSTO.at(tx.logs[2].args._module); - }); + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); }); - describe("verify the data of STO", async () => { + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it('Should fail to launch the STO due to endTime is 0', async () => { + let bytesSTO = encodeModuleCall(STOParameters, [0]); + + await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); + }); + + it('Should successfully attach the STO factory with the security token', async () => { + endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time + let bytesSTO = encodeModuleCall(STOParameters, [endTime]); - it("Should verify the configuration of the STO", async() => { - assert.equal( - (await I_PreSaleSTO.endTime.call()).toNumber(), - endTime, - "STO Configuration doesn't set as expected" - ); - }); + const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); - it("Should get the permissions", async() => { - let perm = await I_PreSaleSTO.getPermissions.call(); - assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), "PRE_SALE_ADMIN"); - }); + assert.equal(tx.logs[2].args._type, stoKey, "PreSaleSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'PreSaleSTO', + 'PreSaleSTOFactory module was not added' + ); + I_PreSaleSTO = PreSaleSTO.at(tx.logs[2].args._module); }); + }); - describe("Buy tokens", async() => { - - it("Should allocate the tokens -- failed due to investor not on whitelist", async () => { - - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0)); - }); - - it("Should Buy the tokens", async() => { - fromTime = latestTime(); - toTime = fromTime + duration.days(100); - expiryTime = toTime + duration.days(100); - - // Add the Investor in to the whitelist - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(duration.days(1)); - await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_issuer }); - - assert.equal( - (await I_PreSaleSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); - console.log(await I_PreSaleSTO.getNumberInvestors.call()); - assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 1); - // assert.isTrue(false); - - }); - - it("Should allocate the tokens -- failed due to msg.sender is not pre sale admin", async () => { - - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver })); - }); - - it("Should allocate tokens to multiple investors", async() => { - fromTime = latestTime(); - toTime = fromTime + duration.days(100); - expiryTime = toTime + duration.days(100); - - // Add the Investor in to the whitelist - let tx1 = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx1.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - - // Add the Investor in to the whitelist - let tx2 = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx2.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); - - await I_PreSaleSTO.allocateTokensMulti([account_investor2, account_investor3], [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], [0,0], [web3.utils.toWei('1000', 'ether'), web3.utils.toWei('1000', 'ether')], {from: account_issuer }); - - assert.equal( - (await I_PreSaleSTO.getRaised.call(1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 2000 - ); - assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 3); - }); - - it("Should failed at the time of buying the tokens -- Because STO has started", async() => { - await increaseTime(duration.days(100)); // increased beyond the end time of the STO - - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, {from: account_issuer})); - }); + describe('verify the data of STO', async () => { + it('Should verify the configuration of the STO', async () => { + assert.equal((await I_PreSaleSTO.endTime.call()).toNumber(), endTime, "STO Configuration doesn't set as expected"); + }); + it('Should get the permissions', async () => { + let perm = await I_PreSaleSTO.getPermissions.call(); + assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), 'PRE_SALE_ADMIN'); }); + }); - describe("Reclaim poly sent to STO by mistake", async() => { - - it("Should fail to reclaim POLY because token contract address is 0 address", async() => { - let value = web3.utils.toWei('100','ether'); - await I_PolyToken.getTokens(value, account_investor1); - await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); - - - await catchRevert(I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); - }); - - it("Should successfully reclaim POLY", async() => { - let value = web3.utils.toWei('100','ether'); - await I_PolyToken.getTokens(value, account_investor1); - let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); - let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); - let initContractBalance = await I_PolyToken.balanceOf(I_PreSaleSTO.address); - - await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); - await I_PreSaleSTO.reclaimERC20(I_PolyToken.address, { from: token_owner }); - assert.equal((await I_PolyToken.balanceOf(account_investor1)).toNumber(), initInvestorBalance.sub(value).toNumber(), "tokens are not transfered out from investor account"); - assert.equal((await I_PolyToken.balanceOf(token_owner)).toNumber(), initOwnerBalance.add(value).add(initContractBalance).toNumber(), "tokens are not added to the owner account"); - assert.equal((await I_PolyToken.balanceOf(I_PreSaleSTO.address)).toNumber(), 0, "tokens are not trandfered out from STO contract"); - }); + describe('Buy tokens', async () => { + it('Should allocate the tokens -- failed due to investor not on whitelist', async () => { + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0)); }); - describe("Test cases for the PresaleSTOFactory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_PreSaleSTOFactory.setupCost.call(),0); - assert.equal(await I_PreSaleSTOFactory.getType.call(),3); - assert.equal(web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()) - .replace(/\u0000/g, ''), - "PreSaleSTO", - "Wrong Module added"); - assert.equal(await I_PreSaleSTOFactory.getDescription.call(), - "Allows Issuer to configure pre-sale token allocations", - "Wrong Module added"); - assert.equal(await I_PreSaleSTOFactory.getTitle.call(), - "PreSale STO", - "Wrong Module added"); - assert.equal(await I_PreSaleSTOFactory.getInstructions.call(), - "Configure and track pre-sale token allocations", - "Wrong Module added"); - let tags = await I_PreSaleSTOFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''),"Presale"); - }); - }); + it('Should Buy the tokens', async () => { + fromTime = latestTime(); + toTime = fromTime + duration.days(100); + expiryTime = toTime + duration.days(100); + + // Add the Investor in to the whitelist + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); + + // Jump time + await increaseTime(duration.days(1)); + await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, { + from: account_issuer + }); + + assert.equal((await I_PreSaleSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); + console.log(await I_PreSaleSTO.getNumberInvestors.call()); + assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 1); + // assert.isTrue(false); + }); + it('Should allocate the tokens -- failed due to msg.sender is not pre sale admin', async () => { + await catchRevert( + I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, { + from: account_fundsReceiver + }) + ); + }); + + it('Should allocate tokens to multiple investors', async () => { + fromTime = latestTime(); + toTime = fromTime + duration.days(100); + expiryTime = toTime + duration.days(100); + + // Add the Investor in to the whitelist + let tx1 = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx1.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); + + // Add the Investor in to the whitelist + let tx2 = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx2.logs[0].args._investor, account_investor3, 'Failed in adding the investor in whitelist'); + + await I_PreSaleSTO.allocateTokensMulti( + [account_investor2, account_investor3], + [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], + [0, 0], + [web3.utils.toWei('1000', 'ether'), web3.utils.toWei('1000', 'ether')], + { from: account_issuer } + ); + + assert.equal((await I_PreSaleSTO.getRaised.call(1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2000); + assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 3); + }); + + it('Should failed at the time of buying the tokens -- Because STO has started', async () => { + await increaseTime(duration.days(100)); // increased beyond the end time of the STO + + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, { from: account_issuer })); + }); + }); + + describe('Reclaim poly sent to STO by mistake', async () => { + it('Should fail to reclaim POLY because token contract address is 0 address', async () => { + let value = web3.utils.toWei('100', 'ether'); + await I_PolyToken.getTokens(value, account_investor1); + await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); + + await catchRevert(I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); + }); + + it('Should successfully reclaim POLY', async () => { + let value = web3.utils.toWei('100', 'ether'); + await I_PolyToken.getTokens(value, account_investor1); + let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); + let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); + let initContractBalance = await I_PolyToken.balanceOf(I_PreSaleSTO.address); + + await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); + await I_PreSaleSTO.reclaimERC20(I_PolyToken.address, { from: token_owner }); + assert.equal( + (await I_PolyToken.balanceOf(account_investor1)).toNumber(), + initInvestorBalance.sub(value).toNumber(), + 'tokens are not transfered out from investor account' + ); + assert.equal( + (await I_PolyToken.balanceOf(token_owner)).toNumber(), + initOwnerBalance + .add(value) + .add(initContractBalance) + .toNumber(), + 'tokens are not added to the owner account' + ); + assert.equal((await I_PolyToken.balanceOf(I_PreSaleSTO.address)).toNumber(), 0, 'tokens are not trandfered out from STO contract'); + }); + }); + + describe('Test cases for the PresaleSTOFactory', async () => { + it('should get the exact details of the factory', async () => { + assert.equal(await I_PreSaleSTOFactory.setupCost.call(), 0); + assert.equal(await I_PreSaleSTOFactory.getType.call(), 3); + assert.equal(web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()).replace(/\u0000/g, ''), 'PreSaleSTO', 'Wrong Module added'); + assert.equal( + await I_PreSaleSTOFactory.getDescription.call(), + 'Allows Issuer to configure pre-sale token allocations', + 'Wrong Module added' + ); + assert.equal(await I_PreSaleSTOFactory.getTitle.call(), 'PreSale STO', 'Wrong Module added'); + assert.equal( + await I_PreSaleSTOFactory.getInstructions.call(), + 'Configure and track pre-sale token allocations', + 'Wrong Module added' + ); + let tags = await I_PreSaleSTOFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Presale'); + }); + }); }); diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 15efa13b9..df5a294ea 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -24,211 +24,199 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('SecurityTokenRegistry', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_fundsReceiver; + let account_delegate; + let account_temp; + let dummy_token; + + let balanceOfReceiver; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(100); + + let ID_snap; + const message = 'Transaction Should Fail!!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_SecurityTokenRegistryV2; + let I_DummySTOFactory; + let I_STVersion; + let I_SecurityToken; + let I_DummySTO; + let I_PolyToken; + let I_STFactory; + let I_STFactory002; + let I_SecurityToken002; + let I_STFactory003; + let I_PolymathRegistry; + let I_SecurityTokenRegistryProxy; + let I_STRProxied; + let I_MRProxied; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = 'Demo Token'; + const symbol = 'DET'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + //Security Token Detials (Version 2) + const name2 = 'Demo2 Token'; + const symbol2 = 'DET2'; + const tokenDetails2 = 'This is equity type of issuance'; + + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + const newRegFee = web3.utils.toWei('300'); + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + + // Capped STO details + const cap = web3.utils.toWei('10000'); + const someString = 'Hello string'; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[9]; + account_investor2 = accounts[6]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + account_temp = accounts[8]; + token_owner = account_issuer; + dummy_token = accounts[3]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_fundsReceiver; - let account_delegate; - let account_temp; - let dummy_token; - - let balanceOfReceiver; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(100); - - let ID_snap; - const message = "Transaction Should Fail!!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_SecurityTokenRegistryV2; - let I_DummySTOFactory; - let I_STVersion; - let I_SecurityToken; - let I_DummySTO; - let I_PolyToken; - let I_STFactory; - let I_STFactory002; - let I_SecurityToken002; - let I_STFactory003; - let I_PolymathRegistry; - let I_SecurityTokenRegistryProxy; - let I_STRProxied; - let I_MRProxied; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = "Demo Token"; - const symbol = "DET"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - - //Security Token Detials (Version 2) - const name2 = "Demo2 Token"; - const symbol2 = "DET2"; - const tokenDetails2 = "This is equity type of issuance"; - - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - const newRegFee = web3.utils.toWei("300"); - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - - // Capped STO details - const cap = web3.utils.toWei("10000"); - const someString = "Hello string"; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[9]; - account_investor2 = accounts[6]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - account_temp = accounts[8]; - token_owner = account_issuer; - dummy_token = accounts[3]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - - // Step 6: Deploy the STversionProxy contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + // STEP 3: Deploy the GeneralDelegateManagerFactory - // STEP 8: Deploy the CappedSTOFactory + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 1000 * Math.pow(10, 18), 0, 0,{ from: token_owner }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "TestSTOFactory contract was not deployed" - ); + // Step 6: Deploy the STversionProxy contract - // Step 9: Deploy the SecurityTokenRegistry + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + // STEP 8: Deploy the CappedSTOFactory - // Step 9 (a): Deploy the proxy - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 1000 * Math.pow(10, 18), 0, 0, { from: token_owner }); - // Step 10: Deploy the FeatureRegistry + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'TestSTOFactory contract was not deployed' + ); - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + // Step 9: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 9 (a): Deploy the proxy + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - assert.notEqual( - I_FeatureRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "FeatureRegistry contract was not deployed", - ); + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'FeatureRegistry contract was not deployed' + ); - //Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + //Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // STEP 4: Register the Modules with the ModuleRegistry contract + // STEP 4: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - console.log(` + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -244,832 +232,856 @@ contract('SecurityTokenRegistry', accounts => { DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Test the initialize the function', async () => { + it('Should successfully update the implementation address -- fail because polymathRegistry address is 0x', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + '0x0000000000000000000000000000000000000000', + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), + 'tx-> revert because polymathRegistry address is 0x' + ); + }); + + it('Should successfully update the implementation address -- fail because STFactory address is 0x', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + '0x0000000000000000000000000000000000000000', + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), + 'tx-> revert because STFactory address is 0x' + ); + }); + + it('Should successfully update the implementation address -- fail because STLaunch fee is 0', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + 0, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), + 'tx-> revert because STLaunch fee is 0' + ); + }); + + it('Should successfully update the implementation address -- fail because tickerRegFee fee is 0', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + 0, + I_PolyToken.address, + account_polymath + ]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), + 'tx-> revert because tickerRegFee is 0' + ); + }); + + it('Should successfully update the implementation address -- fail because PolyToken address is 0x', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + '0x0000000000000000000000000000000000000000', + account_polymath + ]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), + 'tx-> revert because PolyToken address is 0x' + ); + }); + + it('Should successfully update the implementation address -- fail because owner address is 0x', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + '0x0000000000000000000000000000000000000000' + ]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), + 'tx-> revert because owner address is 0x' + ); + }); + + it('Should successfully update the implementation address', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + }); + }); + + describe(' Test cases of the registerTicker', async () => { + it('verify the intial parameters', async () => { + let intialised = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('initialised')); + assert.isTrue(intialised, 'Should be true'); + + let expiry = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('expiryLimit')); + assert.equal(expiry.toNumber(), 5184000, 'Expiry limit should be equal to 60 days'); + + let polytoken = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('polyToken')); + assert.equal(polytoken, I_PolyToken.address, 'Should be the polytoken address'); + + let stlaunchFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('stLaunchFee')); + assert.equal(stlaunchFee.toNumber(), initRegFee, 'Should be provided reg fee'); + + let tickerRegFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('tickerRegFee')); + assert.equal(tickerRegFee.toNumber(), tickerRegFee, 'Should be provided reg fee'); + + let polymathRegistry = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('polymathRegistry')); + assert.equal(polymathRegistry, I_PolymathRegistry.address, 'Should be the address of the polymath registry'); + + let owner = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')); + assert.equal(owner, account_polymath, 'Should be the address of the registry owner'); + }); + + it("Can't call the intialize function again", async () => { + catchRevert( + I_STRProxied.initialize( + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ), + "tx revert -> Can't call the intialize function again" + ); + }); + + it('Should fail to register ticker if tickerRegFee not approved', async () => { + catchRevert( + I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }), + 'tx revert -> POLY allowance not provided for registration fee' + ); + }); + + it('Should fail to register ticker if owner is 0x', async () => { + await I_PolyToken.getTokens(initRegFee, account_temp); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp }); + + catchRevert( + I_STRProxied.registerTicker('0x0000000000000000000000000000000000000000', symbol, name, { from: account_temp }), + 'tx revert -> owner should not be 0x' + ); + }); + + it('Should fail to register ticker due to the symbol length is 0', async () => { + catchRevert(I_STRProxied.registerTicker(account_temp, '', name, { from: account_temp }), 'tx revert -> Symbol Length is 0'); + }); + + it('Should fail to register ticker due to the symbol length is greater than 10', async () => { + catchRevert( + I_STRProxied.registerTicker(account_temp, 'POLYMATHNET', name, { from: account_temp }), + 'tx revert -> Symbol Length is greater than 10' + ); + }); + + it('Should register the ticker before the generation of the security token', async () => { + let tx = await I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); + }); + + it('Should fail to register same symbol again', async () => { + // Give POLY to token issuer + await I_PolyToken.getTokens(initRegFee, token_owner); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + // Call registration function + catchRevert( + I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }), + 'tx revert -> Symbol is already alloted to someone else' + ); + }); + + it('Should successfully register pre registerd ticker if expiry is reached', async () => { + await increaseTime(5184000 + 100); // 60(5184000) days of expiry + 100 sec for buffer + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); + }); + + it('Should fail to register ticker if registration is paused', async () => { + await I_STRProxied.pause({ from: account_polymath }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + + catchRevert(I_STRProxied.registerTicker(token_owner, 'AAA', name, { from: token_owner }), 'tx revert -> Registration is paused'); + }); + + it('Should fail to pause if already paused', async () => { + catchRevert(I_STRProxied.pause({ from: account_polymath }), 'tx revert -> Registration is already paused'); + }); + + it('Should successfully register ticker if registration is unpaused', async () => { + await I_STRProxied.unpause({ from: account_polymath }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, 'AAA', name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, 'AAA', `Symbol should be AAA`); + }); + + it('Should fail to unpause if already unpaused', async () => { + catchRevert(I_STRProxied.unpause({ from: account_polymath }), 'tx revert -> Registration is already unpaused'); + }); + }); + + describe('Test cases for the expiry limit', async () => { + it('Should fail to set the expiry limit because msg.sender is not owner', async () => { + catchRevert(I_STRProxied.changeExpiryLimit(duration.days(10), { from: account_temp }), 'tx revert -> msg.sender is not owner'); + }); + + it('Should successfully set the expiry limit', async () => { + await I_STRProxied.changeExpiryLimit(duration.days(10), { from: account_polymath }); + assert.equal( + (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('expiryLimit'))).toNumber(), + duration.days(10), + 'Failed to change the expiry limit' + ); + }); + + it('Should fail to set the expiry limit because new expiry limit is lesser than one day', async () => { + catchRevert( + I_STRProxied.changeExpiryLimit(duration.seconds(5000), { from: account_polymath }), + 'tx revert -> New expiry limit is lesser than one day' + ); + }); + }); + + describe('Test cases for the getTickerDetails', async () => { + it('Should get the details of the symbol', async () => { + let tx = await I_STRProxied.getTickerDetails.call(symbol); + assert.equal(tx[0], token_owner, 'Should equal to the rightful owner of the ticker'); + assert.equal(tx[3], name, `Name of the token should equal to ${name}`); + assert.equal(tx[4], false, 'Status if the symbol should be undeployed -- false'); + }); + + it('Should get the details of unregistered token', async () => { + let tx = await I_STRProxied.getTickerDetails.call('TORO'); + assert.equal(tx[0], '0x0000000000000000000000000000000000000000', 'Should be 0x as ticker is not exists in the registry'); + assert.equal(tx[3], '', 'Should be an empty string'); + assert.equal(tx[4], false, 'Status if the symbol should be undeployed -- false'); + }); + }); + + describe('Generate SecurityToken', async () => { + it('Should get the ticker details successfully and prove the data is not storing in to the logic contract', async () => { + let data = await I_STRProxied.getTickerDetails(symbol, { from: token_owner }); + assert.equal(data[0], token_owner, 'Token owner should be equal'); + assert.equal(data[3], name, 'Name of the token should match with the registered symbol infor'); + assert.equal(data[4], false, 'Token is not launched yet so it should return False'); + data = await I_SecurityTokenRegistry.getTickerDetails(symbol, { from: token_owner }); + console.log('This is the data from the original securityTokenRegistry contract'); + assert.equal(data[0], '0x0000000000000000000000000000000000000000', 'Token owner should be 0x'); + }); + + it('Should fail to generate new security token if fee not provided', async () => { + await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner }); + + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + 'tx revert -> POLY allowance not provided for registration fee' + ); + }); + + it('Should fail to generate token if registration is paused', async () => { + await I_STRProxied.pause({ from: account_polymath }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + 'tx revert -> Registration is paused' + ); + }); + + it('Should fail to generate the securityToken -- Because ticker length is 0', async () => { + await I_STRProxied.unpause({ from: account_polymath }); + + catchRevert( + I_STRProxied.generateSecurityToken(name, '', tokenDetails, false, { from: token_owner }), + 'tx revert -> Zero ticker length is not allowed' + ); + }); + + it('Should fail to generate the securityToken -- Because name length is 0', async () => { + catchRevert( + I_STRProxied.generateSecurityToken('', symbol, tokenDetails, false, { from: token_owner }), + 'tx revert -> 0 name length is not allowed' + ); + }); + + it('Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker', async () => { + catchRevert( + I_STRProxied.generateSecurityToken('', symbol, tokenDetails, false, { from: account_temp }), + 'tx revert -> Because msg.sender is not the rightful owner of the ticker' + ); + }); + + it('Should generate the new security token with the same symbol as registered above', async () => { + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTrasnferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey, `Should be equal to the ${transferManagerKey}`); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); + + it('Should fail to generate the SecurityToken when token is already deployed with the same symbol', async () => { + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + 'tx revert -> Because ticker is already in use' + ); + }); + }); + + describe('Generate SecurityToken v2', async () => { + it('Should deploy the st version 2', async () => { + // Step 7: Deploy the STFactory contract + + I_STFactory002 = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + + assert.notEqual( + I_STFactory002.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'STFactory002 contract was not deployed' + ); + await I_STRProxied.setProtocolVersion(I_STFactory002.address, 0, 2, 0, { from: account_polymath }); + let _protocol = await I_STRProxied.getProtocolVersion.call(); + assert.equal(_protocol[0], 0); + assert.equal(_protocol[1], 2); + assert.equal(_protocol[2], 0); + }); + + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol2, name2, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, symbol2, `Symbol should be ${symbol2}`); + }); + + it('Should generate the new security token with version 2', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); + + I_SecurityToken002 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + let tokens = await I_STRProxied.getTokensByOwner.call(token_owner); + assert.equal(tokens[0], I_SecurityToken.address); + assert.equal(tokens[1], I_SecurityToken002.address); + + const log = await promisifyLogWatch(I_SecurityToken002.ModuleAdded({ from: _blockNo }), 1); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); + }); + + describe('Deploy the new SecurityTokenRegistry', async () => { + it('Should deploy the new SecurityTokenRegistry contract logic', async () => { + I_SecurityTokenRegistryV2 = await SecurityTokenRegistryMock.new({ from: account_polymath }); + assert.notEqual( + I_SecurityTokenRegistryV2.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + }); + + it('Should fail to upgrade the logic contract of the STRProxy -- bad owner', async () => { + await I_STRProxied.pause({ from: account_polymath }); + + catchRevert( + I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryV2.address, { from: account_temp }), + 'tx revert -> bad owner' + ); + }); + + it('Should upgrade the logic contract into the STRProxy', async () => { + await I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryV2.address, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + assert.isTrue(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')), 'Paused value should be false'); + }); + + it('Should check the old data persist or not', async () => { + let data = await I_STRProxied.getTickerDetails.call(symbol); + assert.equal(data[0], token_owner, 'Should be equal to the token owner address'); + assert.equal(data[3], name, 'Should be equal to the name of the token that is provided earlier'); + assert.isTrue(data[4], 'Token status should be deployed == true'); + }); + + it('Should unpause the logic contract', async () => { + await I_STRProxied.unpause({ from: account_polymath }); + assert.isFalse(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')), 'Paused value should be false'); + }); + }); + + describe('Generate custom tokens', async () => { + it('Should fail if msg.sender is not polymath', async () => { + catchRevert( + I_STRProxied.modifySecurityToken('LOGAN', 'LOG', account_temp, dummy_token, 'I am custom ST', latestTime(), { + from: account_delegate + }), + 'tx revert -> msg.sender is not polymath account' + ); + }); + + it('Should fail to generate the custom security token -- name should not be 0 length ', async () => { + catchRevert( + I_STRProxied.modifySecurityToken('', 'LOG', account_temp, dummy_token, 'I am custom ST', latestTime(), { from: account_polymath }), + 'tx revert -> name should not be 0 length' + ); + }); + + it('Should fail if ST address is 0 address', async () => { + catchRevert( + I_STRProxied.modifySecurityToken('LOGAN', 'LOG', account_temp, 0, 'I am custom ST', latestTime(), { from: account_polymath }), + 'tx revert -> Security token address is 0' + ); + }); + + it('Should fail if symbol length is 0', async () => { + catchRevert( + I_STRProxied.modifySecurityToken('', '', account_temp, dummy_token, 'I am custom ST', latestTime(), { from: account_polymath }), + 'tx revert -> zero length of the symbol is not allowed' + ); + }); + + it('Should fail to generate the custom ST -- deployedAt param is 0', async () => { + catchRevert( + I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, 'I am custom ST', 0, { from: account_polymath }), + 'tx revert -> because deployedAt param is 0' + ); + }); + + it('Should successfully generate custom token', async () => { + // Register the new ticker -- Fulfiling the TickerStatus.ON condition + await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp }); + let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + await I_STRProxied.registerTicker(account_temp, 'LOG', 'LOGAN', { from: account_temp }); + tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + // Generating the ST + let tx = await I_STRProxied.modifySecurityToken('LOGAN', 'LOG', account_temp, dummy_token, 'I am custom ST', latestTime(), { + from: account_polymath + }); + tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + assert.equal(tx.logs[1].args._ticker, 'LOG', 'Symbol should match with the registered symbol'); + assert.equal( + tx.logs[1].args._securityTokenAddress, + dummy_token, + `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken` + ); + let symbolDetails = await I_STRProxied.getTickerDetails('LOG'); + assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); + assert.equal(symbolDetails[3], 'LOGAN', `Name of the symbol should be LOGAN`); + }); + + it('Should successfully generate the custom token', async () => { + // Fulfilling the TickerStatus.NN condition + // + // await catchRevert(I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath})); + // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); + // await increaseTime(duration.days(1)); + let tx = await I_STRProxied.modifySecurityToken('LOGAN2', 'LOG2', account_temp, dummy_token, 'I am custom ST', latestTime(), { + from: account_polymath + }); + assert.equal(tx.logs[1].args._ticker, 'LOG2', 'Symbol should match with the registered symbol'); + assert.equal( + tx.logs[1].args._securityTokenAddress, + dummy_token, + `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken` + ); + assert.equal(tx.logs[0].args._owner, account_temp, `Token owner should be ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, 'LOG2', `Symbol should be LOG2`); + let symbolDetails = await I_STRProxied.getTickerDetails('LOG2'); + assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); + assert.equal(symbolDetails[3], 'LOGAN2', `Name of the symbol should be LOGAN`); + }); + }); + + describe('Test case for modifyTicker', async () => { + it('Should add the custom ticker --failed because of bad owner', async () => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', latestTime(), latestTime() + duration.days(10), false, { + from: account_temp + }), + 'tx revert -> failed beacause of bad owner0' + ); + }); + + it('Should add the custom ticker --fail ticker length should not be 0', async () => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, '', 'Ether', latestTime(), latestTime() + duration.days(10), false, { + from: account_polymath + }), + 'tx revert -> failed beacause ticker length should not be 0' + ); + }); + + it('Should add the custom ticker --failed because time should not be 0', async () => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', 0, latestTime() + duration.days(10), false, { from: account_polymath }), + 'tx revert -> failed because time should not be 0' + ); + }); + + it('Should add the custom ticker --failed because registeration date is greater than the expiryDate', async () => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', latestTime(), latestTime() - duration.minutes(10), false, { + from: account_polymath + }), + 'tx revert -> failed because registeration date is greater than the expiryDate' + ); + }); + + it('Should add the custom ticker --failed because owner should not be 0x', async () => { + catchRevert( + I_STRProxied.modifyTicker( + '0x000000000000000000000000000000000000000000', + 'ETH', + 'Ether', + latestTime(), + latestTime() + duration.minutes(10), + false, + { from: account_polymath } + ), + 'tx revert -> failed because owner should not be 0x' + ); + }); + + it('Should add the new custom ticker', async () => { + let tx = await I_STRProxied.modifyTicker(account_temp, 'ETH', 'Ether', latestTime(), latestTime() + duration.minutes(10), false, { + from: account_polymath + }); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, 'ETH', 'Should be equal to ETH'); + }); + + it('Should change the details of the existing ticker', async () => { + let tx = await I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', latestTime(), latestTime() + duration.minutes(10), false, { + from: account_polymath + }); + assert.equal(tx.logs[0].args._owner, token_owner); + }); + }); + + describe('Test cases for the transferTickerOwnership()', async () => { + it('Should able to transfer the ticker ownership -- failed because token is not deployed having the same ticker', async () => { + catchRevert( + I_STRProxied.transferTickerOwnership(account_issuer, 'ETH', { from: account_temp }), + 'tx revert -> failed because token is not deployed having the same ticker' + ); + }); + + it('Should able to transfer the ticker ownership -- failed because new owner is 0x', async () => { + await I_SecurityToken002.transferOwnership(account_temp, { from: token_owner }); + catchRevert( + I_STRProxied.transferTickerOwnership('0x00000000000000000000000000000000000000000', symbol2, { from: token_owner }), + 'tx revert -> failed because new owner is 0x' + ); + }); + + it('Should able to transfer the ticker ownership -- failed because ticker is of zero length', async () => { + catchRevert( + I_STRProxied.transferTickerOwnership(account_temp, '', { from: token_owner }), + 'tx revert -> failed because ticker is of zero length' + ); + }); + + it('Should able to transfer the ticker ownership', async () => { + let tx = await I_STRProxied.transferTickerOwnership(account_temp, symbol2, { from: token_owner, gas: 5000000 }); + assert.equal(tx.logs[0].args._newOwner, account_temp); + let symbolDetails = await I_STRProxied.getTickerDetails.call(symbol2); + assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); + assert.equal(symbolDetails[3], name2, `Name of the symbol should be ${name2}`); + }); + }); + + describe('Test case for the changeSecurityLaunchFee()', async () => { + it('Should able to change the STLaunchFee-- failed because of bad owner', async () => { + catchRevert( + I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei('500'), { from: account_temp }), + 'tx revert -> failed because of bad owner' + ); + }); + + it('Should able to change the STLaunchFee-- failed because of putting the same fee', async () => { + catchRevert( + I_STRProxied.changeSecurityLaunchFee(initRegFee, { from: account_polymath }), + 'tx revert -> failed because of putting the same fee' + ); + }); + + it('Should able to change the STLaunchFee', async () => { + let tx = await I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei('500'), { from: account_polymath }); + assert.equal(tx.logs[0].args._newFee, web3.utils.toWei('500')); + let stLaunchFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3('stLaunchFee')); + assert.equal(stLaunchFee, web3.utils.toWei('500')); + }); + }); + + describe('Test cases for the changeExpiryLimit()', async () => { + it('Should able to change the ExpiryLimit-- failed because of bad owner', async () => { + catchRevert(I_STRProxied.changeExpiryLimit(duration.days(15), { from: account_temp }), 'tx revert -> failed because of bad owner'); + }); + + it('Should able to change the ExpiryLimit-- failed because expirylimit is less than 1 day', async () => { + catchRevert( + I_STRProxied.changeExpiryLimit(duration.minutes(50), { from: account_polymath }), + 'tx revert -> failed because expirylimit is less than 1 day' + ); + }); + + it('Should able to change the ExpiryLimit', async () => { + let tx = await I_STRProxied.changeExpiryLimit(duration.days(20), { from: account_polymath }); + assert.equal(tx.logs[0].args._newExpiry, duration.days(20)); + let expiry = await I_STRProxied.getUintValues(web3.utils.soliditySha3('expiryLimit')); + assert.equal(expiry, duration.days(20)); + }); + }); + + describe('Test cases for the changeTickerRegistrationFee()', async () => { + it('Should able to change the TickerRegFee-- failed because of bad owner', async () => { + catchRevert( + I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei('500'), { from: account_temp }), + 'tx revert -> failed because of bad owner' + ); + }); + + it('Should able to change the TickerRegFee-- failed because of putting the same fee', async () => { + catchRevert( + I_STRProxied.changeTickerRegistrationFee(initRegFee, { from: account_polymath }), + 'tx revert -> failed because of putting the same fee' + ); + }); + + it('Should able to change the TickerRegFee', async () => { + let tx = await I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei('400'), { from: account_polymath }); + assert.equal(tx.logs[0].args._newFee, web3.utils.toWei('400')); + let tickerRegFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3('tickerRegFee')); + assert.equal(tickerRegFee, web3.utils.toWei('400')); + }); + + it('Should fail to register the ticker with the old fee', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + catchRevert( + I_STRProxied.registerTicker(token_owner, 'POLY', 'Polymath', { from: token_owner }), + 'tx revert -> failed because of ticker registeration fee gets change' + ); + }); + + it('Should register the ticker with the new fee', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('1000'), token_owner); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, 'POLY', 'Polymath', { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, 'POLY', `Symbol should be POLY`); + }); + + it('Should fail to launch the securityToken with the old launch fee', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + catchRevert( + I_STRProxied.generateSecurityToken('Polymath', 'POLY', tokenDetails, false, { from: token_owner }), + 'tx revert -> failed because of old launch fee' + ); + }); + + it('Should launch the the securityToken', async () => { + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: token_owner }); + let tx = await I_STRProxied.generateSecurityToken('Polymath', 'POLY', tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, 'POLY', "SecurityToken doesn't get deployed"); + }); + }); + + describe('Test case for the update poly token', async () => { + it('Should change the polytoken address -- failed because of bad owner', async () => { + catchRevert(I_STRProxied.updatePolyTokenAddress(dummy_token, { from: account_temp }), 'tx revert -> failed because of bad owner'); + }); + + it('Should change the polytoken address -- failed because of 0x address', async () => { + catchRevert( + I_STRProxied.updatePolyTokenAddress('0x0000000000000000000000000000000000000000000', { from: account_polymath }), + 'tx revert -> failed because 0x address' + ); + }); + + it('Should successfully change the polytoken address', async () => { + let _id = await takeSnapshot(); + await I_STRProxied.updatePolyTokenAddress(dummy_token, { from: account_polymath }); + assert.equal(await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('polyToken')), dummy_token); + await revertToSnapshot(_id); + }); + }); + + describe('Test cases for getters', async () => { + it('Should get the security token address', async () => { + let address = await I_STRProxied.getSecurityTokenAddress.call(symbol); + assert.equal(address, I_SecurityToken.address); + }); + + it('Should get the security token data', async () => { + let data = await I_STRProxied.getSecurityTokenData.call(I_SecurityToken.address); + assert.equal(data[0], symbol); + assert.equal(data[1], token_owner); + }); + + it('Should get the tickers by owner', async () => { + let tickersList = await I_STRProxied.getTickersByOwner.call(token_owner); + assert.equal(tickersList.length, 4); + let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + assert.equal(tickersListArray.length, 3); + }); + }); + + describe('Test case for the Removing the ticker', async () => { + it('Should remove the ticker from the polymath ecosystem -- bad owner', async () => { + catchRevert( + I_STRProxied.removeTicker(symbol2, { from: account_investor1 }), + 'tx revert -> failed because msg.sender should be account_polymath' + ); + }); + + it("Should remove the ticker from the polymath ecosystem -- fail because ticker doesn't exist in the ecosystem", async () => { + catchRevert( + I_STRProxied.removeTicker('HOLA', { from: account_polymath }), + "tx revert -> failed because ticker doesn't exist in the polymath ecosystem" + ); }); - describe("Test the initialize the function", async() => { - - it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, ["0x0000000000000000000000000000000000000000", I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), - "tx-> revert because polymathRegistry address is 0x" - ); - }) - - it("Should successfully update the implementation address -- fail because STFactory address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, "0x0000000000000000000000000000000000000000", initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), - "tx-> revert because STFactory address is 0x" - ); - }); - - it("Should successfully update the implementation address -- fail because STLaunch fee is 0", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, 0, initRegFee, I_PolyToken.address, account_polymath]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), - "tx-> revert because STLaunch fee is 0" - ); - }); - - it("Should successfully update the implementation address -- fail because tickerRegFee fee is 0", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, 0, I_PolyToken.address, account_polymath]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), - "tx-> revert because tickerRegFee is 0" - ); - }); - - it("Should successfully update the implementation address -- fail because PolyToken address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, "0x0000000000000000000000000000000000000000", account_polymath]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), - "tx-> revert because PolyToken address is 0x" - ); - }); - - it("Should successfully update the implementation address -- fail because owner address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, "0x0000000000000000000000000000000000000000"]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), - "tx-> revert because owner address is 0x" - ); - }); - - it("Should successfully update the implementation address", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - }); - }) - - - describe(" Test cases of the registerTicker", async() => { - - it("verify the intial parameters", async() => { - let intialised = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("initialised")); - assert.isTrue(intialised, "Should be true"); - - let expiry = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit")); - assert.equal(expiry.toNumber(), 5184000, "Expiry limit should be equal to 60 days"); - - let polytoken = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")); - assert.equal(polytoken, I_PolyToken.address, "Should be the polytoken address"); - - let stlaunchFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("stLaunchFee")); - assert.equal(stlaunchFee.toNumber(), initRegFee, "Should be provided reg fee"); - - let tickerRegFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("tickerRegFee")); - assert.equal(tickerRegFee.toNumber(), tickerRegFee, "Should be provided reg fee"); - - let polymathRegistry = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry")); - assert.equal(polymathRegistry, I_PolymathRegistry.address, "Should be the address of the polymath registry"); - - let owner = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("owner")); - assert.equal(owner, account_polymath, "Should be the address of the registry owner"); - }); - - it("Can't call the intialize function again", async() => { - catchRevert( - I_STRProxied.initialize(I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath), - "tx revert -> Can't call the intialize function again" - ); - }) - - it("Should fail to register ticker if tickerRegFee not approved", async() => { - catchRevert( - I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }), - "tx revert -> POLY allowance not provided for registration fee" - ); - }); - - it("Should fail to register ticker if owner is 0x", async() => { - await I_PolyToken.getTokens(initRegFee, account_temp); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); - - catchRevert( - I_STRProxied.registerTicker("0x0000000000000000000000000000000000000000", symbol, name, { from: account_temp }), - "tx revert -> owner should not be 0x" - ); - }); - - it("Should fail to register ticker due to the symbol length is 0", async() => { - catchRevert( - I_STRProxied.registerTicker(account_temp, "", name, { from: account_temp }), - "tx revert -> Symbol Length is 0" - ); - }); - - it("Should fail to register ticker due to the symbol length is greater than 10", async() => { - catchRevert( - I_STRProxied.registerTicker(account_temp, "POLYMATHNET", name, { from: account_temp }), - "tx revert -> Symbol Length is greater than 10" - ); - }); - - it("Should register the ticker before the generation of the security token", async () => { - let tx = await I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); - }); - - it("Should fail to register same symbol again", async() => { - // Give POLY to token issuer - await I_PolyToken.getTokens(initRegFee, token_owner); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - // Call registration function - catchRevert( - I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }), - "tx revert -> Symbol is already alloted to someone else" - ); - }); - - it("Should successfully register pre registerd ticker if expiry is reached", async() => { - await increaseTime(5184000 + 100); // 60(5184000) days of expiry + 100 sec for buffer - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); - }); - - it("Should fail to register ticker if registration is paused", async() => { - await I_STRProxied.pause({ from: account_polymath}); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - - catchRevert( - I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }), - "tx revert -> Registration is paused" - ); - }); - - it("Should fail to pause if already paused", async() => { - catchRevert( - I_STRProxied.pause({ from: account_polymath}), - "tx revert -> Registration is already paused" - ); - }); - - it("Should successfully register ticker if registration is unpaused", async() => { - await I_STRProxied.unpause({ from: account_polymath}); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, "AAA", `Symbol should be AAA`); - }); - - it("Should fail to unpause if already unpaused", async() => { - catchRevert( - I_STRProxied.unpause({ from: account_polymath}), - "tx revert -> Registration is already unpaused" - ); - }); - }); - - describe("Test cases for the expiry limit", async() => { - - it("Should fail to set the expiry limit because msg.sender is not owner", async() => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_temp}), - "tx revert -> msg.sender is not owner" - ); - }); - - it("Should successfully set the expiry limit", async() => { - await I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_polymath}); - assert.equal( - (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))) - .toNumber(), - duration.days(10), - "Failed to change the expiry limit"); - }); - - it("Should fail to set the expiry limit because new expiry limit is lesser than one day", async() => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.seconds(5000), {from: account_polymath}), - "tx revert -> New expiry limit is lesser than one day" - ) - }); - }); - - describe("Test cases for the getTickerDetails", async() => { - - it("Should get the details of the symbol", async() => { - let tx = await I_STRProxied.getTickerDetails.call(symbol); - assert.equal(tx[0], token_owner, "Should equal to the rightful owner of the ticker"); - assert.equal(tx[3], name, `Name of the token should equal to ${name}`); - assert.equal(tx[4], false, "Status if the symbol should be undeployed -- false"); - }); - - it("Should get the details of unregistered token", async() => { - let tx = await I_STRProxied.getTickerDetails.call("TORO"); - assert.equal(tx[0], "0x0000000000000000000000000000000000000000", "Should be 0x as ticker is not exists in the registry"); - assert.equal(tx[3], "", "Should be an empty string"); - assert.equal(tx[4], false, "Status if the symbol should be undeployed -- false"); - }); - }); - - describe("Generate SecurityToken", async() => { - - it("Should get the ticker details successfully and prove the data is not storing in to the logic contract", async() => { - let data = await I_STRProxied.getTickerDetails(symbol, {from: token_owner}); - assert.equal(data[0], token_owner, "Token owner should be equal"); - assert.equal(data[3], name, "Name of the token should match with the registered symbol infor"); - assert.equal(data[4], false, "Token is not launched yet so it should return False"); - data = await I_SecurityTokenRegistry.getTickerDetails(symbol, {from:token_owner}); - console.log("This is the data from the original securityTokenRegistry contract"); - assert.equal(data[0], '0x0000000000000000000000000000000000000000', "Token owner should be 0x"); - }) - - it("Should fail to generate new security token if fee not provided", async() => { - await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner}); - - catchRevert( - I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), - "tx revert -> POLY allowance not provided for registration fee" - ); - }); - - it("Should fail to generate token if registration is paused", async() => { - await I_STRProxied.pause({ from: account_polymath}); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - - catchRevert( - I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), - "tx revert -> Registration is paused" - ); - }); - - it("Should fail to generate the securityToken -- Because ticker length is 0", async() => { - await I_STRProxied.unpause({ from: account_polymath}); - - catchRevert( - I_STRProxied.generateSecurityToken(name, "", tokenDetails, false, { from: token_owner }), - "tx revert -> Zero ticker length is not allowed" - ) - }) - - it("Should fail to generate the securityToken -- Because name length is 0", async() => { - catchRevert( - I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: token_owner }), - "tx revert -> 0 name length is not allowed" - ); - }) - - it("Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker", async() => { - catchRevert( - I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp }), - "tx revert -> Because msg.sender is not the rightful owner of the ticker" - ) - }) - - it("Should generate the new security token with the same symbol as registered above", async () => { - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTrasnferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey, `Should be equal to the ${transferManagerKey}`); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should fail to generate the SecurityToken when token is already deployed with the same symbol", async() => { - catchRevert( - I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), - "tx revert -> Because ticker is already in use" - ); - }) - - }); - - describe("Generate SecurityToken v2", async() => { - - it("Should deploy the st version 2", async() => { - // Step 7: Deploy the STFactory contract - - I_STFactory002 = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory002.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory002 contract was not deployed", - ); - await I_STRProxied.setProtocolVersion(I_STFactory002.address, 0, 2, 0, { from: account_polymath }); - let _protocol = await I_STRProxied.getProtocolVersion.call(); - assert.equal(_protocol[0], 0); - assert.equal(_protocol[1], 2); - assert.equal(_protocol[2], 0); - }); - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol2, name2, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, symbol2, `Symbol should be ${symbol2}`); - }); - - it("Should generate the new security token with version 2", async() => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); - - I_SecurityToken002 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - let tokens = await I_STRProxied.getTokensByOwner.call(token_owner); - assert.equal(tokens[0], I_SecurityToken.address); - assert.equal(tokens[1], I_SecurityToken002.address); - - const log = await promisifyLogWatch(I_SecurityToken002.ModuleAdded({from: _blockNo}), 1); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - }); - - describe("Deploy the new SecurityTokenRegistry", async() => { - - it("Should deploy the new SecurityTokenRegistry contract logic", async() => { - I_SecurityTokenRegistryV2 = await SecurityTokenRegistryMock.new({ from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistryV2.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - }); - - it("Should fail to upgrade the logic contract of the STRProxy -- bad owner", async() => { - await I_STRProxied.pause({from: account_polymath}); - - catchRevert( - I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_temp}), - "tx revert -> bad owner" - ) - }) - - it("Should upgrade the logic contract into the STRProxy", async() =>{ - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - assert.isTrue(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")), "Paused value should be false"); - }); - - it("Should check the old data persist or not", async() => { - let data = await I_STRProxied.getTickerDetails.call(symbol); - assert.equal(data[0], token_owner, "Should be equal to the token owner address"); - assert.equal(data[3], name, "Should be equal to the name of the token that is provided earlier"); - assert.isTrue(data[4], "Token status should be deployed == true"); - }); - - it("Should unpause the logic contract", async() => { - await I_STRProxied.unpause({from: account_polymath}); - assert.isFalse(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")), "Paused value should be false"); - }); - }) - - describe("Generate custom tokens", async() => { - - it("Should fail if msg.sender is not polymath", async() => { - catchRevert( - I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_delegate}), - "tx revert -> msg.sender is not polymath account" - ); - }); - - it("Should fail to generate the custom security token -- name should not be 0 length ", async() => { - catchRevert( - I_STRProxied.modifySecurityToken("", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}), - "tx revert -> name should not be 0 length" - ); - }); - - it("Should fail if ST address is 0 address", async() => { - catchRevert( - I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", latestTime(), {from: account_polymath}), - "tx revert -> Security token address is 0" - ); - }); - - it("Should fail if symbol length is 0", async() => { - catchRevert( - I_STRProxied.modifySecurityToken("", "", account_temp, dummy_token, "I am custom ST",latestTime(), {from: account_polymath}), - "tx revert -> zero length of the symbol is not allowed" - ); - }); - - it("Should fail to generate the custom ST -- deployedAt param is 0", async() => { - catchRevert( - I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, "I am custom ST", 0, {from: account_polymath}), - "tx revert -> because deployedAt param is 0" - ); - }); - - it("Should successfully generate custom token", async() => { - // Register the new ticker -- Fulfiling the TickerStatus.ON condition - await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); - let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - await I_STRProxied.registerTicker(account_temp, "LOG", "LOGAN", { from : account_temp }); - tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - // Generating the ST - let tx = await I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); - tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - assert.equal(tx.logs[1].args._ticker, "LOG", "Symbol should match with the registered symbol"); - assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token,`Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); - let symbolDetails = await I_STRProxied.getTickerDetails("LOG"); - assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); - assert.equal(symbolDetails[3], "LOGAN", `Name of the symbol should be LOGAN`); - }); - - it("Should successfully generate the custom token", async() => { - // Fulfilling the TickerStatus.NN condition - // - // await catchRevert(I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath})); - // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); - // await increaseTime(duration.days(1)); - let tx = await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); - assert.equal(tx.logs[1].args._ticker, "LOG2", "Symbol should match with the registered symbol"); - assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token, `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); - assert.equal(tx.logs[0].args._owner, account_temp, `Token owner should be ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, "LOG2", `Symbol should be LOG2`); - let symbolDetails = await I_STRProxied.getTickerDetails("LOG2"); - assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); - assert.equal(symbolDetails[3], "LOGAN2", `Name of the symbol should be LOGAN`); - }); - - }); - - describe("Test case for modifyTicker", async() => { - - it("Should add the custom ticker --failed because of bad owner", async() => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_temp}), - "tx revert -> failed beacause of bad owner0" - ); - }) - - it("Should add the custom ticker --fail ticker length should not be 0", async() => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, "", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_polymath}), - "tx revert -> failed beacause ticker length should not be 0" - ); - }) - - it("Should add the custom ticker --failed because time should not be 0", async() => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", 0, (latestTime() + duration.days(10)), false, {from: account_polymath}), - "tx revert -> failed because time should not be 0" - ); - }) - - it("Should add the custom ticker --failed because registeration date is greater than the expiryDate", async() => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() - duration.minutes(10)), false, {from: account_polymath}), - "tx revert -> failed because registeration date is greater than the expiryDate" - ); - }) - - it("Should add the custom ticker --failed because owner should not be 0x", async() => { - catchRevert( - I_STRProxied.modifyTicker("0x000000000000000000000000000000000000000000", "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}), - "tx revert -> failed because owner should not be 0x" - ); - }) - - it("Should add the new custom ticker", async() => { - let tx = await I_STRProxied.modifyTicker(account_temp, "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); - assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, "ETH", "Should be equal to ETH"); - }) - - it("Should change the details of the existing ticker", async() => { - let tx = await I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); - assert.equal(tx.logs[0].args._owner, token_owner); - }); - - }); - - describe("Test cases for the transferTickerOwnership()", async() => { - - it("Should able to transfer the ticker ownership -- failed because token is not deployed having the same ticker", async() => { - catchRevert( - I_STRProxied.transferTickerOwnership(account_issuer, "ETH", {from: account_temp}), - "tx revert -> failed because token is not deployed having the same ticker" - ) - }) - - it("Should able to transfer the ticker ownership -- failed because new owner is 0x", async() => { - - await I_SecurityToken002.transferOwnership(account_temp, {from: token_owner}); - catchRevert( - I_STRProxied.transferTickerOwnership("0x00000000000000000000000000000000000000000", symbol2, {from: token_owner}), - "tx revert -> failed because new owner is 0x" - ) - }) - - it("Should able to transfer the ticker ownership -- failed because ticker is of zero length", async() => { - catchRevert( - I_STRProxied.transferTickerOwnership(account_temp, "", {from: token_owner}), - "tx revert -> failed because ticker is of zero length" - ); - }) - - it("Should able to transfer the ticker ownership", async() => { - let tx = await I_STRProxied.transferTickerOwnership(account_temp, symbol2, {from: token_owner, gas: 5000000 }); - assert.equal(tx.logs[0].args._newOwner, account_temp); - let symbolDetails = await I_STRProxied.getTickerDetails.call(symbol2); - assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); - assert.equal(symbolDetails[3], name2, `Name of the symbol should be ${name2}`); - }) - }) - - describe("Test case for the changeSecurityLaunchFee()", async() => { - - it("Should able to change the STLaunchFee-- failed because of bad owner", async() => { - catchRevert( - I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_temp}), - "tx revert -> failed because of bad owner" - ); - }); - - it("Should able to change the STLaunchFee-- failed because of putting the same fee", async() => { - catchRevert( - I_STRProxied.changeSecurityLaunchFee(initRegFee, {from: account_polymath}), - "tx revert -> failed because of putting the same fee" - ) - }); - - it("Should able to change the STLaunchFee", async() => { - let tx = await I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_polymath}); - assert.equal(tx.logs[0].args._newFee, web3.utils.toWei("500")); - let stLaunchFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3("stLaunchFee")); - assert.equal(stLaunchFee, web3.utils.toWei("500")); - }); - - }) - - describe("Test cases for the changeExpiryLimit()", async() => { - - it("Should able to change the ExpiryLimit-- failed because of bad owner", async() => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.days(15), {from: account_temp}), - "tx revert -> failed because of bad owner" - ) - }); - - it("Should able to change the ExpiryLimit-- failed because expirylimit is less than 1 day", async() => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.minutes(50), {from: account_polymath}), - "tx revert -> failed because expirylimit is less than 1 day" - ); - }); - - it("Should able to change the ExpiryLimit", async() => { - let tx = await I_STRProxied.changeExpiryLimit(duration.days(20), {from: account_polymath}); - assert.equal(tx.logs[0].args._newExpiry, duration.days(20)); - let expiry = await I_STRProxied.getUintValues(web3.utils.soliditySha3("expiryLimit")); - assert.equal(expiry, duration.days(20)); - }); - }) - - describe("Test cases for the changeTickerRegistrationFee()", async() => { - - it("Should able to change the TickerRegFee-- failed because of bad owner", async() => { - catchRevert( - I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("500"), {from: account_temp}), - "tx revert -> failed because of bad owner" - ) - }); - - it("Should able to change the TickerRegFee-- failed because of putting the same fee", async() => { - catchRevert( - I_STRProxied.changeTickerRegistrationFee(initRegFee, {from: account_polymath}), - "tx revert -> failed because of putting the same fee" - ); - }); - - it("Should able to change the TickerRegFee", async() => { - let tx = await I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("400"), {from: account_polymath}); - assert.equal(tx.logs[0].args._newFee, web3.utils.toWei("400")); - let tickerRegFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3("tickerRegFee")); - assert.equal(tickerRegFee, web3.utils.toWei("400")); - }); - - it("Should fail to register the ticker with the old fee", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - catchRevert( - I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }), - "tx revert -> failed because of ticker registeration fee gets change" - ); - }) - - it("Should register the ticker with the new fee", async() => { - await I_PolyToken.getTokens(web3.utils.toWei("1000"), token_owner); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, "POLY", `Symbol should be POLY`); - }); - - it("Should fail to launch the securityToken with the old launch fee", async() => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - catchRevert( - I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }), - "tx revert -> failed because of old launch fee" - ) - }) - - it("Should launch the the securityToken", async() => { - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner}); - let tx = await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, "POLY", "SecurityToken doesn't get deployed"); - }); - }); - - describe("Test case for the update poly token", async() => { - - it("Should change the polytoken address -- failed because of bad owner", async() => { - catchRevert( - I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_temp}), - "tx revert -> failed because of bad owner" - ); - }) - - it("Should change the polytoken address -- failed because of 0x address", async() => { - catchRevert( - I_STRProxied.updatePolyTokenAddress("0x0000000000000000000000000000000000000000000", {from: account_polymath}), - "tx revert -> failed because 0x address" - ); - }) - - it("Should successfully change the polytoken address", async() => { - let _id = await takeSnapshot(); - await I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_polymath}); - assert.equal(await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")), dummy_token); - await revertToSnapshot(_id); - }); - }) - - describe("Test cases for getters", async() => { - - it("Should get the security token address", async() => { - let address = await I_STRProxied.getSecurityTokenAddress.call(symbol); - assert.equal(address, I_SecurityToken.address); - }); - - it("Should get the security token data", async() => { - let data = await I_STRProxied.getSecurityTokenData.call(I_SecurityToken.address); - assert.equal(data[0], symbol); - assert.equal(data[1], token_owner); - }); - - it("Should get the tickers by owner", async() => { - let tickersList = await I_STRProxied.getTickersByOwner.call(token_owner); - assert.equal(tickersList.length, 4); - let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - assert.equal(tickersListArray.length, 3); - }); - - }); - - describe("Test case for the Removing the ticker", async() => { - - it("Should remove the ticker from the polymath ecosystem -- bad owner", async() => { - catchRevert( - I_STRProxied.removeTicker(symbol2, {from: account_investor1}), - "tx revert -> failed because msg.sender should be account_polymath" - ) - }) - - it("Should remove the ticker from the polymath ecosystem -- fail because ticker doesn't exist in the ecosystem", async() => { - catchRevert( - I_STRProxied.removeTicker("HOLA", {from: account_polymath}), - "tx revert -> failed because ticker doesn't exist in the polymath ecosystem" - ) - }) - - it("Should successfully remove the ticker from the polymath ecosystem", async() => { - let tx = await I_STRProxied.removeTicker(symbol2, {from: account_polymath}); - assert.equal(tx.logs[0].args._ticker, symbol2, "Ticker doesn't get deleted successfully"); - }); - }) - - describe(" Test cases of the registerTicker", async() => { - - it("Should register the ticker 1", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); - let tx = await I_STRProxied.registerTicker(account_temp, "TOK1", "", { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, "TOK1", `Symbol should be TOK1`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - - it("Should register the ticker 2", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); - let tx = await I_STRProxied.registerTicker(account_temp, "TOK2", "", { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, "TOK2", `Symbol should be TOK2`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - - it("Should register the ticker 3", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); - let tx = await I_STRProxied.registerTicker(account_temp, "TOK3", "", { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, "TOK3", `Symbol should be TOK3`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - - it("Should successfully remove the ticker 2", async() => { - let tx = await I_STRProxied.removeTicker("TOK2", {from: account_polymath}); - assert.equal(tx.logs[0].args._ticker, "TOK2", "Ticker doesn't get deleted successfully"); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - - it("Should modify ticker 1", async() => { - let tx = await I_STRProxied.modifyTicker(account_temp, "TOK1", "TOKEN 1", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); - assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, "TOK1", "Should be equal to TOK1"); - assert.equal(tx.logs[0].args._name, "TOKEN 1", "Should be equal to TOKEN 1"); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }) - - it("Should modify ticker 3", async() => { - let tx = await I_STRProxied.modifyTicker(account_temp, "TOK3", "TOKEN 3", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); - assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, "TOK3", "Should be equal to TOK3"); - assert.equal(tx.logs[0].args._name, "TOKEN 3", "Should be equal to TOKEN 3"); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }) - - }); - describe("Test cases for IRegistry functionality", async() => { - - describe("Test cases for reclaiming funds", async() => { - - it("Should successfully reclaim POLY tokens", async() => { - I_PolyToken.transfer(I_STRProxied.address, web3.utils.toWei("1"), { from: token_owner }); - let bal1 = await I_PolyToken.balanceOf.call(account_polymath); - await I_STRProxied.reclaimERC20(I_PolyToken.address); - let bal2 = await I_PolyToken.balanceOf.call(account_polymath); - assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); - }); - - }); - - describe("Test cases for pausing the contract", async() => { - - it("Should fail to pause if msg.sender is not owner", async() => { - catchRevert( - I_STRProxied.pause({ from: account_temp }), - "tx revert -> msg.sender should be account_polymath" - ) - }); - - it("Should successfully pause the contract", async() => { - await I_STRProxied.pause({ from: account_polymath }); - let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); - assert.isOk(status); - }); - - it("Should fail to unpause if msg.sender is not owner", async() => { - catchRevert( - I_STRProxied.unpause({ from: account_temp }), - "tx revert -> msg.sender should be account_polymath" - ) - }); - - it("Should successfully unpause the contract", async() => { - await I_STRProxied.unpause({ from: account_polymath }); - let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); - assert.isNotOk(status); - }); - - }); + it('Should successfully remove the ticker from the polymath ecosystem', async () => { + let tx = await I_STRProxied.removeTicker(symbol2, { from: account_polymath }); + assert.equal(tx.logs[0].args._ticker, symbol2, "Ticker doesn't get deleted successfully"); + }); + }); + + describe(' Test cases of the registerTicker', async () => { + it('Should register the ticker 1', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('1000'), { from: account_temp }); + let tx = await I_STRProxied.registerTicker(account_temp, 'TOK1', '', { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, 'TOK1', `Symbol should be TOK1`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + + it('Should register the ticker 2', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('1000'), { from: account_temp }); + let tx = await I_STRProxied.registerTicker(account_temp, 'TOK2', '', { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, 'TOK2', `Symbol should be TOK2`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + + it('Should register the ticker 3', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('1000'), { from: account_temp }); + let tx = await I_STRProxied.registerTicker(account_temp, 'TOK3', '', { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, 'TOK3', `Symbol should be TOK3`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + it('Should successfully remove the ticker 2', async () => { + let tx = await I_STRProxied.removeTicker('TOK2', { from: account_polymath }); + assert.equal(tx.logs[0].args._ticker, 'TOK2', "Ticker doesn't get deleted successfully"); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); + it('Should modify ticker 1', async () => { + let tx = await I_STRProxied.modifyTicker(account_temp, 'TOK1', 'TOKEN 1', latestTime(), latestTime() + duration.minutes(10), false, { + from: account_polymath + }); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, 'TOK1', 'Should be equal to TOK1'); + assert.equal(tx.logs[0].args._name, 'TOKEN 1', 'Should be equal to TOKEN 1'); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + + it('Should modify ticker 3', async () => { + let tx = await I_STRProxied.modifyTicker(account_temp, 'TOK3', 'TOKEN 3', latestTime(), latestTime() + duration.minutes(10), false, { + from: account_polymath + }); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, 'TOK3', 'Should be equal to TOK3'); + assert.equal(tx.logs[0].args._name, 'TOKEN 3', 'Should be equal to TOKEN 3'); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + }); + describe('Test cases for IRegistry functionality', async () => { + describe('Test cases for reclaiming funds', async () => { + it('Should successfully reclaim POLY tokens', async () => { + I_PolyToken.transfer(I_STRProxied.address, web3.utils.toWei('1'), { from: token_owner }); + let bal1 = await I_PolyToken.balanceOf.call(account_polymath); + await I_STRProxied.reclaimERC20(I_PolyToken.address); + let bal2 = await I_PolyToken.balanceOf.call(account_polymath); + assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); + }); + }); + + describe('Test cases for pausing the contract', async () => { + it('Should fail to pause if msg.sender is not owner', async () => { + catchRevert(I_STRProxied.pause({ from: account_temp }), 'tx revert -> msg.sender should be account_polymath'); + }); + + it('Should successfully pause the contract', async () => { + await I_STRProxied.pause({ from: account_polymath }); + let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); + assert.isOk(status); + }); + + it('Should fail to unpause if msg.sender is not owner', async () => { + catchRevert(I_STRProxied.unpause({ from: account_temp }), 'tx revert -> msg.sender should be account_polymath'); + }); + + it('Should successfully unpause the contract', async () => { + await I_STRProxied.unpause({ from: account_polymath }); + let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); + assert.isNotOk(status); + }); + }); + }); }); diff --git a/test/o_security_token.js b/test/o_security_token.js index 021154f8d..4fbec99e3 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -23,210 +23,202 @@ const TokenBurner = artifacts.require('./MockTokenBurner.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('SecurityToken', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_investor3; + let account_affiliate1; + let account_affiliate2; + let account_fundsReceiver; + let account_delegate; + let account_temp; + let account_controller; + let address_zero = '0x0000000000000000000000000000000000000000'; + + let balanceOfReceiver; + // investor Details + let fromTime; + let toTime; + let expiryTime; + + let ID_snap; + const message = 'Transaction Should Fail!!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_CappedSTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_STRProxied; + let I_MRProxied; + let I_CappedSTO; + let I_PolyToken; + let I_TokenBurner; + let I_PolymathRegistry; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = 'Demo Token'; + const symbol = 'DET'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + let snap_Id; + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + + // delagate details + const delegateDetails = 'I am delegate ..'; + const TM_Perm = 'FLAGS'; + const TM_Perm_Whitelist = 'WHITELIST'; + + // Capped STO details + let startTime; + let endTime; + const cap = web3.utils.toWei('10000'); + const rate = 1000; + const fundRaiseType = [0]; + const cappedSTOSetupCost = web3.utils.toWei('20000', 'ether'); + const maxCost = cappedSTOSetupCost; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_affiliate1 = accounts[2]; + account_affiliate2 = accounts[3]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + account_investor2 = accounts[6]; + account_investor3 = accounts[7]; + account_temp = accounts[8]; + account_investor1 = accounts[9]; + + token_owner = account_issuer; + account_controller = account_temp; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4 (a): Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + address_zero, + 'GeneralTransferManagerFactory contract was not deployed' + ); + + // STEP 4 (b): Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + address_zero, + 'GeneralDelegateManagerFactory contract was not deployed' + ); + + // STEP 4 (c): Deploy the CappedSTOFactory + + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); + + assert.notEqual(I_CappedSTOFactory.address.valueOf(), address_zero, 'CappedSTOFactory contract was not deployed'); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // Step 6: Deploy the STFactory contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_investor3; - let account_affiliate1; - let account_affiliate2; - let account_fundsReceiver; - let account_delegate; - let account_temp; - let account_controller; - let address_zero = "0x0000000000000000000000000000000000000000"; - - let balanceOfReceiver; - // investor Details - let fromTime; - let toTime; - let expiryTime; - - let ID_snap; - const message = "Transaction Should Fail!!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_CappedSTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_STRProxied; - let I_MRProxied; - let I_CappedSTO; - let I_PolyToken; - let I_TokenBurner; - let I_PolymathRegistry; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = "Demo Token"; - const symbol = "DET"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - let snap_Id; - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // delagate details - const delegateDetails = "I am delegate .."; - const TM_Perm = 'FLAGS'; - const TM_Perm_Whitelist = 'WHITELIST'; - - // Capped STO details - let startTime; - let endTime; - const cap = web3.utils.toWei("10000"); - const rate = 1000; - const fundRaiseType = [0]; - const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); - const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_affiliate1 = accounts[2]; - account_affiliate2 = accounts[3]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - account_investor2 = accounts[6]; - account_investor3 = accounts[7]; - account_temp = accounts[8]; - account_investor1 = accounts[9]; - - token_owner = account_issuer; - account_controller = account_temp; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4 (a): Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - address_zero, - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 4 (b): Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - address_zero, - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 4 (c): Deploy the CappedSTOFactory - - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - address_zero, - "CappedSTOFactory contract was not deployed" - ); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 7: Deploy the SecurityTokenRegistry contract - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -242,854 +234,781 @@ contract('SecurityToken', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol); + }); + + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.toUtf8(log.args._name), 'GeneralTransferManager'); + }); + + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + assert.notEqual(I_GeneralTransferManager.address.valueOf(), address_zero, 'GeneralTransferManager contract was not deployed'); + }); + + it('Should mint the tokens before attaching the STO -- fail only be called by the owner', async () => { + let fromTime = latestTime(); + let toTime = fromTime + duration.days(100); + let expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist(account_affiliate1, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 6000000 + }); + assert.equal(tx.logs[0].args._investor, account_affiliate1, 'Failed in adding the investor in whitelist'); + await catchRevert(I_SecurityToken.mint(account_investor1, 100 * Math.pow(10, 18), { from: account_delegate })); + }); + + it('Should mint the tokens before attaching the STO', 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(), 100); + }); + + it('Should mint the multi tokens before attaching the STO -- fail only be called by the owner', async () => { + let fromTime = latestTime(); + let toTime = fromTime + duration.days(100); + let expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist(account_affiliate2, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_affiliate2, 'Failed in adding the investor in whitelist'); + await catchRevert( + I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [100 * Math.pow(10, 18), 110 * Math.pow(10, 18)], { + from: account_delegate, + gas: 500000 + }) + ); + }); + + it('Should mintMulti', async () => { + await catchRevert( + I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [100 * Math.pow(10, 18)], { from: token_owner, gas: 500000 }) + ); + }); + + it('Should mint the tokens for multiple afiliated investors before attaching the STO', 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(), 200); + let balance2 = await I_SecurityToken.balanceOf(account_affiliate2); + assert.equal(balance2.dividedBy(new BigNumber(10).pow(18)).toNumber(), 110); + }); + + it('Should finish the minting -- fail because feature is not activated', async () => { + await catchRevert(I_SecurityToken.freezeMinting({ from: token_owner })); + }); + + it('Should finish the minting -- fail to activate the feature because msg.sender is not polymath', async () => { + await catchRevert(I_FeatureRegistry.setFeatureStatus('freezeMintingAllowed', true, { from: token_owner })); + }); + + it('Should finish the minting -- successfully activate the feature', async () => { + await catchRevert(I_FeatureRegistry.setFeatureStatus('freezeMintingAllowed', false, { from: account_polymath })); + + 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 })); + + await catchRevert(I_FeatureRegistry.setFeatureStatus('freezeMintingAllowed', true, { from: account_polymath })); + }); + + it('Should finish the minting -- fail because msg.sender is not the owner', async () => { + await catchRevert(I_SecurityToken.freezeMinting({ from: account_temp })); + }); + + it('Should finish minting & restrict the further minting', async () => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({ from: token_owner }); + + await catchRevert(I_SecurityToken.mint(account_affiliate1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); + 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); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); + + it('Should fail to attach the STO factory because max cost too small', 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 }); + + await catchRevert( + I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei('1000', 'ether'), 0, { from: token_owner }) + ); + }); + + 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._type, 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); + 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 }); + + await catchRevert(I_SecurityToken.mint(account_affiliate1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); + await revertToSnapshot(id); + }); + }); + + describe('Module related functions', async () => { + it('Should get the modules of the securityToken by index', 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], 3); + assert.equal(moduleData[5], 0); + assert.equal(moduleData[6], 0); + }); + + it('Should get the modules of the securityToken by index (not added into the security token yet)', async () => { + let moduleData = await I_SecurityToken.getModule.call(token_owner); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), ''); + assert.equal(moduleData[1], address_zero); + }); + + it('Should get the modules of the securityToken by name', async () => { + let moduleList = await I_SecurityToken.getModulesByName.call('CappedSTO'); + assert.isTrue(moduleList.length == 1, 'Only one STO'); + let moduleData = await I_SecurityToken.getModule.call(moduleList[0]); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'CappedSTO'); + assert.equal(moduleData[1], I_CappedSTO.address); + }); + + it('Should get the modules of the securityToken by name (not added into the security token yet)', async () => { + let moduleData = await I_SecurityToken.getModulesByName.call('GeneralPermissionManager'); + assert.isTrue(moduleData.length == 0, 'No Permission Manager'); + }); + + it('Should get the modules of the securityToken by name (not added into the security token yet)', async () => { + let moduleData = await I_SecurityToken.getModulesByName.call('CountTransferManager'); + assert.isTrue(moduleData.length == 0, 'No Permission Manager'); + }); + + it('Should fail in updating the token details', async () => { + await catchRevert(I_SecurityToken.updateTokenDetails('new token details', { from: account_delegate })); + }); + + it('Should update the token details', async () => { + let log = await I_SecurityToken.updateTokenDetails('new token details', { from: token_owner }); + assert.equal(log.logs[0].args._newDetails, 'new token details'); + }); + + it('Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner', async () => { + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: account_temp })); + }); + + it('Should fail to remove the module - module not archived', async () => { + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: token_owner })); + }); + + it('Should fail to remove the module - incorrect address', async () => { + await catchRevert(I_SecurityToken.removeModule(0, { from: token_owner })); + }); + + it('Should successfully remove the general transfer manager module from the securityToken', async () => { + let key = await takeSnapshot(); + await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }); + let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: token_owner }); + assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); + await revertToSnapshot(key); + }); + + it('Should verify the revertion of snapshot works properly', async () => { + let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'GeneralTransferManager'); + assert.equal(moduleData[1], I_GeneralTransferManager.address); + }); + + it('Should successfully archive the general transfer manager module from the securityToken', async () => { + let tx = await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }); + assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); + let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'GeneralTransferManager'); + assert.equal(moduleData[1], I_GeneralTransferManager.address); + assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); + assert.equal(moduleData[3], true); + }); + + it('Should successfully mint tokens while GTM archived', async () => { + let key = await takeSnapshot(); + await I_SecurityToken.mint(1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 }); + let balance = await I_SecurityToken.balanceOf(1); + assert.equal(balance.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + await revertToSnapshot(key); + }); + + it('Should successfully unarchive the general transfer manager module from the securityToken', async () => { + let tx = await I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from: token_owner }); + assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); + let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'GeneralTransferManager'); + assert.equal(moduleData[1], I_GeneralTransferManager.address); + assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); + assert.equal(moduleData[3], false); + }); + + it('Should fail to mint tokens while GTM unarchived', async () => { + await catchRevert(I_SecurityToken.mint(1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); + }); + + it('Should change the budget of the module - fail incorrect address', async () => { + await catchRevert(I_SecurityToken.changeModuleBudget(0, 100 * Math.pow(10, 18), { from: token_owner })); + }); + + it('Should change the budget of the module', async () => { + let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, 100 * Math.pow(10, 18), { from: token_owner }); + assert.equal(tx.logs[1].args._moduleType, stoKey); + assert.equal(tx.logs[1].args._module, I_CappedSTO.address); + assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + }); + }); + + describe('General Transfer manager Related test cases', async () => { + it('Should Buy the tokens', async () => { + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + // Add the Investor in to the whitelist + + fromTime = latestTime(); + toTime = fromTime + duration.days(100); + expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 6000000 + }); + assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); + // Jump time + await increaseTime(5000); + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }); + + assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); + + assert.equal(await I_CappedSTO.investorCount.call(), 1); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); + + it('Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2', async () => { + await catchRevert(I_SecurityToken.transfer(account_investor2, 10 * Math.pow(10, 18), { from: account_investor1 })); + }); + + it('Should fail to provide the permission to the delegate to change the transfer bools', async () => { + // Add permission to the deletgate (A regesteration process) + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '', 0, 0, { from: token_owner }); + let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); + I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); + }); + + it('Should provide the permission to the delegate to change the transfer bools', async () => { + // Add permission to the deletgate (A regesteration process) + await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { + from: token_owner + }); + + assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); + }); + + it('Should fail to activate the bool allowAllTransfer', async () => { + await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from: account_temp })); + }); + + it('Should activate the bool allowAllTransfer', async () => { + ID_snap = await takeSnapshot(); + let tx = await I_GeneralTransferManager.changeAllowAllTransfers(true, { from: account_delegate }); + + assert.isTrue(tx.logs[0].args._allowAllTransfers, 'AllowTransfer variable is not successfully updated'); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.toUtf8(log.args._name),"GeneralTransferManager"); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - assert.notEqual( - I_GeneralTransferManager.address.valueOf(), - address_zero, - "GeneralTransferManager contract was not deployed", - ); - - }); - - it("Should mint the tokens before attaching the STO -- fail only be called by the owner", async() => { - - let fromTime = latestTime(); - let toTime = fromTime + duration.days(100); - let expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_affiliate1, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_affiliate1, "Failed in adding the investor in whitelist"); - await catchRevert(I_SecurityToken.mint(account_investor1, (100 * Math.pow(10, 18)), {from: account_delegate})); - }); - - it("Should mint the tokens before attaching the STO", 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(), 100); - }); - - it("Should mint the multi tokens before attaching the STO -- fail only be called by the owner", async() => { - - let fromTime = latestTime(); - let toTime = fromTime + duration.days(100); - let expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_affiliate2, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_affiliate2, "Failed in adding the investor in whitelist"); - await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18)), (110 * Math.pow(10, 18))], {from: account_delegate, gas: 500000})); - }); - - it("Should mintMulti", async() => { - - await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18))], {from: token_owner, gas: 500000})); + it('Should fail to send tokens with the wrong granularity', async () => { + await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from: account_investor1 })); + }); + + it('Should adjust granularity', async () => { + await catchRevert(I_SecurityToken.changeGranularity(0, { from: token_owner })); + }); + + it('Should adjust granularity', async () => { + await I_SecurityToken.changeGranularity(Math.pow(10, 17), { from: token_owner }); + await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from: account_investor1, gas: 2500000 }); + await I_SecurityToken.transfer(account_investor1, Math.pow(10, 17), { from: accounts[7], gas: 2500000 }); + }); + + it('Should transfer from whitelist investor to non-whitelist investor in first tx and in 2nd tx non-whitelist to non-whitelist transfer', async () => { + await I_SecurityToken.transfer(accounts[7], 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 }); + + assert.equal( + (await I_SecurityToken.balanceOf(accounts[7])).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 10, + "Transfer doesn't take place properly" + ); + + await I_SecurityToken.transfer(account_temp, 5 * Math.pow(10, 18), { from: accounts[7], gas: 2500000 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_temp)).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 5, + "Transfer doesn't take place properly" + ); + await revertToSnapshot(ID_snap); + }); + + it('Should bool allowAllTransfer value is false', async () => { + assert.isFalse(await I_GeneralTransferManager.allowAllTransfers.call(), "reverting of snapshot doesn't works properly"); + }); + + it('Should change the bool allowAllWhitelistTransfers to true', async () => { + ID_snap = await takeSnapshot(); + let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from: account_delegate }); + + assert.isTrue(tx.logs[0].args._allowAllWhitelistTransfers, 'allowAllWhitelistTransfers variable is not successfully updated'); + }); + + it('Should transfer from whitelist investor1 to whitelist investor 2', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); + + await I_SecurityToken.transfer(account_investor2, 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 }); + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 10, + "Transfer doesn't take place properly" + ); + }); + + it('Should transfer from whitelist investor1 to whitelist investor 2 -- value = 0', async () => { + let tx = await I_SecurityToken.transfer(account_investor2, 0, { from: account_investor1, gas: 2500000 }); + assert.equal(tx.logs[0].args.value.toNumber(), 0); + }); + + it('Should transferFrom from one investor to other', async () => { + await I_SecurityToken.approve(account_investor1, 2 * Math.pow(10, 18), { from: account_investor2 }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor3, 'Failed in adding the investor in whitelist'); + let log = await I_SecurityToken.transferFrom(account_investor2, account_investor3, 2 * Math.pow(10, 18), { from: account_investor1 }); + assert.equal(log.logs[0].args.value.toNumber(), 2 * Math.pow(10, 18)); + }); + + it('Should Fail in trasferring from whitelist investor1 to non-whitelist investor', async () => { + await catchRevert(I_SecurityToken.transfer(account_temp, 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 })); + await revertToSnapshot(ID_snap); + }); + + 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 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 () => { + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist, true, { + from: token_owner + }); + + assert.isTrue( + await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist) + ); + }); + + it('Should add the investor in the whitelist by the delegate', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, fromTime, toTime, expiryTime, true, { + from: account_delegate, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_temp, 'Failed in adding the investor in whitelist'); + }); + + it('should account_temp successfully buy the token', async () => { + // 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.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2); + + assert.equal(await I_CappedSTO.investorCount.call(), 2); + + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); + + it('STO should fail to mint tokens after minting is frozen', async () => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({ from: token_owner }); + + await catchRevert( + web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') }) + ); + await revertToSnapshot(id); + }); + + it('Should remove investor from the whitelist by the delegate', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, 0, 0, 0, true, { + from: account_delegate, + gas: 6000000 + }); - it("Should mint the tokens for multiple afiliated investors before attaching the STO", 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(), 200); - let balance2 = await I_SecurityToken.balanceOf(account_affiliate2); - assert.equal(balance2.dividedBy(new BigNumber(10).pow(18)).toNumber(), 110); - }); - - it("Should finish the minting -- fail because feature is not activated", async() => { - - await catchRevert(I_SecurityToken.freezeMinting({from: token_owner})); - }); - - it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async() => { - - await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: token_owner})); - }); - - it("Should finish the minting -- successfully activate the feature", async() => { - await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", false, {from: account_polymath})); - - 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})); - - await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_polymath})); - }); - - it("Should finish the minting -- fail because msg.sender is not the owner", async() => { - - await catchRevert(I_SecurityToken.freezeMinting({from: account_temp})); - }); - - it("Should finish minting & restrict the further minting", async() => { - let id = await takeSnapshot(); - await I_SecurityToken.freezeMinting({from: token_owner}); - - await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); - 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); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); - - it("Should fail to attach the STO factory because max cost too small", 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}); - - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner })); - }); - - 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._type, 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); - 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}); - - await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); - await revertToSnapshot(id); - }); - - }); - - describe("Module related functions", async() => { - it("Should get the modules of the securityToken by index", 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], 3); - assert.equal(moduleData[5], 0); - assert.equal(moduleData[6], 0); - }); - - it("Should get the modules of the securityToken by index (not added into the security token yet)", async () => { - let moduleData = await I_SecurityToken.getModule.call(token_owner); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), ""); - assert.equal(moduleData[1], address_zero); - }); - - it("Should get the modules of the securityToken by name", async () => { - let moduleList = await I_SecurityToken.getModulesByName.call("CappedSTO"); - assert.isTrue(moduleList.length == 1, "Only one STO"); - let moduleData = await I_SecurityToken.getModule.call(moduleList[0]); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "CappedSTO"); - assert.equal(moduleData[1], I_CappedSTO.address); - }); - - it("Should get the modules of the securityToken by name (not added into the security token yet)", async () => { - let moduleData = await I_SecurityToken.getModulesByName.call("GeneralPermissionManager"); - assert.isTrue(moduleData.length == 0, "No Permission Manager"); - }); - - it("Should get the modules of the securityToken by name (not added into the security token yet)", async () => { - let moduleData = await I_SecurityToken.getModulesByName.call("CountTransferManager"); - assert.isTrue(moduleData.length == 0, "No Permission Manager"); - }); - - it("Should fail in updating the token details", async() => { - - await catchRevert(I_SecurityToken.updateTokenDetails("new token details", {from: account_delegate})); - }); - - it("Should update the token details", async() => { - let log = await I_SecurityToken.updateTokenDetails("new token details", {from: token_owner}); - assert.equal(log.logs[0].args._newDetails, "new token details"); - }); - - it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async() => { - - await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp })); - }); - - it("Should fail to remove the module - module not archived", async() => { - - await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner })); + assert.equal(tx.logs[0].args._investor, account_temp, 'Failed in removing the investor from whitelist'); + }); + + it('should account_temp fail in buying the token', async () => { + await catchRevert( + web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') }) + ); + }); + + it('Should freeze the transfers', async () => { + let tx = await I_SecurityToken.freezeTransfers({ from: token_owner }); + assert.isTrue(tx.logs[0].args._status); + }); + + it('Should fail to freeze the transfers', async () => { + await catchRevert(I_SecurityToken.freezeTransfers({ from: token_owner })); + }); + + it('Should fail in buying to tokens', async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, fromTime, toTime, expiryTime, true, { + from: account_delegate, + gas: 6000000 + }); - it("Should fail to remove the module - incorrect address", async() => { - - await catchRevert(I_SecurityToken.removeModule(0, { from : token_owner })); + assert.equal(tx.logs[0].args._investor, account_temp, 'Failed in adding the investor in whitelist'); + + await catchRevert( + web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') }) + ); + }); - it("Should successfully remove the general transfer manager module from the securityToken", async() => { - let key = await takeSnapshot(); - await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); - let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); - assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); - await revertToSnapshot(key); - }); - - it("Should verify the revertion of snapshot works properly", async() => { - let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); - assert.equal(moduleData[1], I_GeneralTransferManager.address); - }); - - - it("Should successfully archive the general transfer manager module from the securityToken", async() => { - let tx = await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); - assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); - let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); - assert.equal(moduleData[1], I_GeneralTransferManager.address); - assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); - assert.equal(moduleData[3], true); - }); - - it("Should successfully mint tokens while GTM archived", async () => { - let key = await takeSnapshot(); - await I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); - let balance = await I_SecurityToken.balanceOf(1); - assert.equal(balance.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - await revertToSnapshot(key); - }); - - it("Should successfully unarchive the general transfer manager module from the securityToken", async() => { - let tx = await I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from : token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); - assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); - let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); - assert.equal(moduleData[1], I_GeneralTransferManager.address); - assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); - assert.equal(moduleData[3], false); - }); - - it("Should fail to mint tokens while GTM unarchived", async () => { - - await catchRevert(I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); - - }); - - it("Should change the budget of the module - fail incorrect address", async() => { - - await catchRevert(I_SecurityToken.changeModuleBudget(0, (100 * Math.pow(10, 18)),{ from : token_owner})); - }); - - - it("Should change the budget of the module", async() => { - let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, (100 * Math.pow(10, 18)),{ from : token_owner}); - assert.equal(tx.logs[1].args._moduleType, stoKey); - assert.equal(tx.logs[1].args._module, I_CappedSTO.address); - assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - }); - - }); - - describe("General Transfer manager Related test cases", async () => { - - it("Should Buy the tokens", async() => { - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - // Add the Investor in to the whitelist - - fromTime = latestTime(); - toTime = fromTime + duration.days(100); - expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); - // Jump time - await increaseTime(5000); - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); - - assert.equal( - (await I_CappedSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); - - assert.equal(await I_CappedSTO.investorCount.call(), 1); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }); - - it("Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1})); - }); - - it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { - - // Add permission to the deletgate (A regesteration process) - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: token_owner}); - let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); - I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); - }); - - it("Should provide the permission to the delegate to change the transfer bools", async () => { - // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: token_owner }); - - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); - }); - - - it("Should fail to activate the bool allowAllTransfer", async() => { - - await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_temp })); - }); - - it("Should activate the bool allowAllTransfer", async() => { - ID_snap = await takeSnapshot(); - let tx = await I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_delegate }); - - assert.isTrue(tx.logs[0].args._allowAllTransfers, "AllowTransfer variable is not successfully updated"); - }); - - - it("Should fail to send tokens with the wrong granularity", async() => { - - await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1})); - }); - - it("Should adjust granularity", async() => { - - await catchRevert(I_SecurityToken.changeGranularity(0, {from: token_owner })); - }); - - it("Should adjust granularity", async() => { - - await I_SecurityToken.changeGranularity(Math.pow(10, 17), {from: token_owner }); - await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1, gas: 2500000 }); - await I_SecurityToken.transfer(account_investor1, Math.pow(10, 17), { from : accounts[7], gas: 2500000}); - }); - - it("Should transfer from whitelist investor to non-whitelist investor in first tx and in 2nd tx non-whitelist to non-whitelist transfer", async() => { - await I_SecurityToken.transfer(accounts[7], (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000}); - - assert.equal( - (await I_SecurityToken.balanceOf(accounts[7])) - .dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10, - "Transfer doesn't take place properly" - ); - - await I_SecurityToken.transfer(account_temp, (5 * Math.pow(10, 18)), { from : accounts[7], gas: 2500000}); - - assert.equal( - (await I_SecurityToken.balanceOf(account_temp)) - .dividedBy(new BigNumber(10).pow(18)).toNumber(), - 5, - "Transfer doesn't take place properly" - ); - await revertToSnapshot(ID_snap); - }); - - it("Should bool allowAllTransfer value is false", async() => { - assert.isFalse(await I_GeneralTransferManager.allowAllTransfers.call(), "reverting of snapshot doesn't works properly"); - }); - - it("Should change the bool allowAllWhitelistTransfers to true", async () => { - ID_snap = await takeSnapshot(); - let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from : account_delegate }); - - assert.isTrue(tx.logs[0].args._allowAllWhitelistTransfers, "allowAllWhitelistTransfers variable is not successfully updated"); - }); - - it("Should transfer from whitelist investor1 to whitelist investor 2", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - - await I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000}); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10, - "Transfer doesn't take place properly" - ); - }); - - it("Should transfer from whitelist investor1 to whitelist investor 2 -- value = 0", async() => { - let tx = await I_SecurityToken.transfer(account_investor2, 0, { from : account_investor1, gas: 2500000}); - assert.equal((tx.logs[0].args.value).toNumber(),0); - }); - - it("Should transferFrom from one investor to other", async() => { - await I_SecurityToken.approve(account_investor1, (2 * Math.pow(10, 18)),{from: account_investor2}); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); - let log = await I_SecurityToken.transferFrom(account_investor2, account_investor3, (2 * Math.pow(10, 18)), {from: account_investor1}); - assert.equal((log.logs[0].args.value).toNumber(), (2 * Math.pow(10, 18))); - }); - - it("Should Fail in trasferring from whitelist investor1 to non-whitelist investor", async() => { - - await catchRevert(I_SecurityToken.transfer(account_temp, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000})); - await revertToSnapshot(ID_snap); - }); - - 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 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() => { - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist, true, { from: token_owner }); - - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist)); - }); - - it("Should add the investor in the whitelist by the delegate", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - fromTime, - toTime, - expiryTime, - true, - { - from: account_delegate, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); - }); - - it("should account_temp successfully buy the token", async() => { - // 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.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 2 - ); - - assert.equal(await I_CappedSTO.investorCount.call(), 2); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }); - - it("STO should fail to mint tokens after minting is frozen", async() => { - let id = await takeSnapshot(); - await I_SecurityToken.freezeMinting({from: token_owner}); - - await catchRevert(web3.eth.sendTransaction({ - from: account_temp, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); - await revertToSnapshot(id); - }); - - it("Should remove investor from the whitelist by the delegate", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - 0, - 0, - 0, - true, - { - from: account_delegate, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_temp, "Failed in removing the investor from whitelist"); - }); - - it("should account_temp fail in buying the token", async() => { - - await catchRevert(web3.eth.sendTransaction({ - from: account_temp, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); - }); - - it("Should freeze the transfers", async() => { - let tx = await I_SecurityToken.freezeTransfers({from: token_owner}); - assert.isTrue(tx.logs[0].args._status); - }); - - it("Should fail to freeze the transfers", async() => { - - await catchRevert(I_SecurityToken.freezeTransfers({from: token_owner})); - }); - - it("Should fail in buying to tokens", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - fromTime, - toTime, - expiryTime, - true, - { - from: account_delegate, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); - - - await catchRevert(web3.eth.sendTransaction({ - from: account_temp, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); - }); - - it("Should fail in trasfering the tokens from one user to another", async() => { - await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); - console.log(await I_SecurityToken.balanceOf(account_investor1)); - - await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp})); - }); - - it("Should unfreeze all the transfers", async() => { - let tx = await I_SecurityToken.unfreezeTransfers({from: token_owner}); - assert.isFalse(tx.logs[0].args._status); - }); - - it("Should freeze the transfers", async() => { - - await catchRevert(I_SecurityToken.unfreezeTransfers({from: token_owner})); - }); - - it("Should able to transfers the tokens from one user to another", async() => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp}); - }); - - it("Should check that the list of investors is correct", async ()=> { - // Hardcode list of expected accounts based on transfers above - let investorsLength = await I_SecurityToken.getInvestorsLength(); - console.log(JSON.stringify(investorsLength)); - let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1, account_temp]; - assert.equal(investorsLength.toNumber(), 4); - console.log("Total Seen Investors: " + investorsLength.toNumber()); - for (let i = 0; i < investorsLength.toNumber(); i++) { - let investor = await I_SecurityToken.investors(i); - assert.equal(investor, expectedAccounts[i]); - } - }); - it("Should fail to set controller status because msg.sender not owner", async() => { - - await catchRevert(I_SecurityToken.setController(account_controller, {from: account_controller})); - }); - - it("Should successfully set controller", async() => { - let tx1 = await I_SecurityToken.setController(account_controller, {from: token_owner}); - - // check event - assert.equal(address_zero, tx1.logs[0].args._oldController, "Event not emitted as expected"); - assert.equal(account_controller, tx1.logs[0].args._newController, "Event not emitted as expected"); - - let tx2 = await I_SecurityToken.setController(address_zero, {from: token_owner}); - - // check event - assert.equal(account_controller, tx2.logs[0].args._oldController, "Event not emitted as expected"); - assert.equal(address_zero, tx2.logs[0].args._newController, "Event not emitted as expected"); - - let tx3 = await I_SecurityToken.setController(account_controller, {from: token_owner}); - - // check event - assert.equal(address_zero, tx3.logs[0].args._oldController, "Event not emitted as expected"); - assert.equal(account_controller, tx3.logs[0].args._newController, "Event not emitted as expected"); - - // check status - let controller = await I_SecurityToken.controller.call(); - assert.equal(account_controller, controller, "Status not set correctly"); - }); - - it("Should force burn the tokens - value too high", async ()=> { - - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - let currentInvestorCount = await I_SecurityToken.investorCount(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", { from: account_controller })); - }); - it("Should force burn the tokens - wrong caller", async ()=> { - - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - let currentInvestorCount = await I_SecurityToken.investorCount(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: token_owner })); - }); - - it("Should burn the tokens", async ()=> { - let currentInvestorCount = await I_SecurityToken.investorCount(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - // console.log(currentInvestorCount.toString(), currentBalance.toString()); - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: account_controller }); - // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); - assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); - let newInvestorCount = await I_SecurityToken.investorCount(); - // console.log(newInvestorCount.toString()); - assert.equal(newInvestorCount.toNumber() + 1, currentInvestorCount.toNumber(), "Investor count drops by one"); - }); - - it("Should prune investor length", async ()=> { - await I_SecurityToken.pruneInvestors(0, 10, {from: token_owner}); - // Hardcode list of expected accounts based on transfers above - let investorsLength = (await I_SecurityToken.getInvestorsLength.call()).toNumber(); - let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1]; - assert.equal(investorsLength, 3); - console.log("Total Seen Investors: " + investorsLength); - for (let i = 0; i < investorsLength; i++) { - let investor = await I_SecurityToken.investors(i); - assert.equal(investor, expectedAccounts[i]); - } - }); - - it("Should check the balance of investor at checkpoint", async() => { - - await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); - }); - - it("Should check the balance of investor at checkpoint", async() => { - let balance = await I_SecurityToken.balanceOfAt(account_investor1, 0); - assert.equal(balance.toNumber(), 0); - }); - }); - - describe("Withdraw Poly", async() => { - - it("Should successfully withdraw the poly", async() => { - - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: account_temp})); - }) - - it("Should successfully withdraw the poly", async() => { - let balanceBefore = await I_PolyToken.balanceOf(token_owner); - await I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: token_owner}); - let balanceAfter = await I_PolyToken.balanceOf(token_owner); - assert.equal((BigNumber(balanceAfter).sub(BigNumber(balanceBefore))).toNumber(), web3.utils.toWei("20000", "ether")); - }); - - it("Should successfully withdraw the poly", async() => { - - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), {from: token_owner})); - }); - }); - - describe("Force Transfer", async() => { - - it("Should fail to forceTransfer because not approved controller", async() => { - await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_investor1})); - }); - - it("Should fail to forceTransfer because insufficient balance", async() => { - - await catchRevert(I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); - }); - - it("Should fail to forceTransfer because recipient is zero address", async() => { - - await catchRevert(I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); - }); - - it("Should successfully forceTransfer", async() => { - let sender = account_investor1; - let receiver = account_investor2; - - let start_investorCount = await I_SecurityToken.investorCount.call(); - let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); - let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); - - let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); - - let end_investorCount = await I_SecurityToken.investorCount.call(); - let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); - let end_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); - - assert.equal(start_investorCount.add(1).toNumber(), end_investorCount.toNumber(), "Investor count not changed"); - assert.equal(start_balInv1.sub(web3.utils.toWei("10", "ether")).toNumber(), end_balInv1.toNumber(), "Investor balance not changed"); - assert.equal(start_balInv2.add(web3.utils.toWei("10", "ether")).toNumber(), end_balInv2.toNumber(), "Investor balance not changed"); - console.log(tx.logs[0].args); - console.log(tx.logs[1].args); - assert.equal(account_controller, tx.logs[0].args._controller, "Event not emitted as expected"); - assert.equal(account_investor1, tx.logs[0].args._from, "Event not emitted as expected"); - assert.equal(account_investor2, tx.logs[0].args._to, "Event not emitted as expected"); - assert.equal(web3.utils.toWei("10", "ether"), tx.logs[0].args._value, "Event not emitted as expected"); - console.log(tx.logs[0].args._verifyTransfer); - assert.equal(false, tx.logs[0].args._verifyTransfer, "Event not emitted as expected"); - assert.equal("reason", web3.utils.hexToUtf8(tx.logs[0].args._data), "Event not emitted as expected"); - - assert.equal(account_investor1, tx.logs[1].args.from, "Event not emitted as expected"); - assert.equal(account_investor2, tx.logs[1].args.to, "Event not emitted as expected"); - assert.equal(web3.utils.toWei("10", "ether"), tx.logs[1].args.value, "Event not emitted as expected"); - }); - - it("Should fail to freeze controller functionality because not owner", async() => { - - await catchRevert(I_SecurityToken.disableController({from: account_investor1})); - }); - - it("Should fail to freeze controller functionality because disableControllerAllowed not activated", async() => { - - await catchRevert(I_SecurityToken.disableController({from: token_owner})); - }); - - it("Should successfully freeze controller functionality", async() => { - let tx1 = await I_FeatureRegistry.setFeatureStatus("disableControllerAllowed", true, {from: account_polymath}); - - // check event - assert.equal("disableControllerAllowed", tx1.logs[0].args._nameKey, "Event not emitted as expected"); - assert.equal(true, tx1.logs[0].args._newStatus, "Event not emitted as expected"); - - let tx2 = await I_SecurityToken.disableController({from: token_owner}); - - // check state - assert.equal(address_zero, await I_SecurityToken.controller.call(), "State not changed"); - assert.equal(true, await I_SecurityToken.controllerDisabled.call(), "State not changed"); - }); - - it("Should fail to freeze controller functionality because already frozen", async() => { - - await catchRevert(I_SecurityToken.disableController({from: token_owner})); - }); - - it("Should fail to set controller because controller functionality frozen", async() => { - - await catchRevert(I_SecurityToken.setController(account_controller, {from: token_owner})); - }); - - it("Should fail to forceTransfer because controller functionality frozen", async() => { - - await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); - }); - - }); + it('Should fail in trasfering the tokens from one user to another', async () => { + await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from: token_owner }); + console.log(await I_SecurityToken.balanceOf(account_investor1)); + + await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_temp })); + }); + it('Should unfreeze all the transfers', async () => { + let tx = await I_SecurityToken.unfreezeTransfers({ from: token_owner }); + assert.isFalse(tx.logs[0].args._status); + }); + + it('Should freeze the transfers', async () => { + await catchRevert(I_SecurityToken.unfreezeTransfers({ from: token_owner })); + }); + + it('Should able to transfers the tokens from one user to another', async () => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_temp }); + }); + + it('Should check that the list of investors is correct', async () => { + // Hardcode list of expected accounts based on transfers above + let investorsLength = await I_SecurityToken.getInvestorsLength(); + console.log(JSON.stringify(investorsLength)); + let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1, account_temp]; + assert.equal(investorsLength.toNumber(), 4); + console.log('Total Seen Investors: ' + investorsLength.toNumber()); + for (let i = 0; i < investorsLength.toNumber(); i++) { + let investor = await I_SecurityToken.investors(i); + assert.equal(investor, expectedAccounts[i]); + } + }); + it('Should fail to set controller status because msg.sender not owner', async () => { + await catchRevert(I_SecurityToken.setController(account_controller, { from: account_controller })); + }); + + it('Should successfully set controller', async () => { + let tx1 = await I_SecurityToken.setController(account_controller, { from: token_owner }); + + // check event + assert.equal(address_zero, tx1.logs[0].args._oldController, 'Event not emitted as expected'); + assert.equal(account_controller, tx1.logs[0].args._newController, 'Event not emitted as expected'); + + let tx2 = await I_SecurityToken.setController(address_zero, { from: token_owner }); + + // check event + assert.equal(account_controller, tx2.logs[0].args._oldController, 'Event not emitted as expected'); + assert.equal(address_zero, tx2.logs[0].args._newController, 'Event not emitted as expected'); + + let tx3 = await I_SecurityToken.setController(account_controller, { from: token_owner }); + + // check event + assert.equal(address_zero, tx3.logs[0].args._oldController, 'Event not emitted as expected'); + assert.equal(account_controller, tx3.logs[0].args._newController, 'Event not emitted as expected'); + + // check status + let controller = await I_SecurityToken.controller.call(); + assert.equal(account_controller, controller, 'Status not set correctly'); + }); + + it('Should force burn the tokens - value too high', async () => { + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); + let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + await catchRevert( + I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei('500', 'ether'), '', { from: account_controller }) + ); + }); + it('Should force burn the tokens - wrong caller', async () => { + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); + let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance, '', { from: token_owner })); + }); + + it('Should burn the tokens', async () => { + let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + // console.log(currentInvestorCount.toString(), currentBalance.toString()); + let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, '', { from: account_controller }); + // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); + assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); + let newInvestorCount = await I_SecurityToken.investorCount(); + // console.log(newInvestorCount.toString()); + assert.equal(newInvestorCount.toNumber() + 1, currentInvestorCount.toNumber(), 'Investor count drops by one'); + }); + + it('Should prune investor length', async () => { + await I_SecurityToken.pruneInvestors(0, 10, { from: token_owner }); + // Hardcode list of expected accounts based on transfers above + let investorsLength = (await I_SecurityToken.getInvestorsLength.call()).toNumber(); + let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1]; + assert.equal(investorsLength, 3); + console.log('Total Seen Investors: ' + investorsLength); + for (let i = 0; i < investorsLength; i++) { + let investor = await I_SecurityToken.investors(i); + assert.equal(investor, expectedAccounts[i]); + } + }); + + it('Should check the balance of investor at checkpoint', async () => { + await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); + }); + + it('Should check the balance of investor at checkpoint', async () => { + let balance = await I_SecurityToken.balanceOfAt(account_investor1, 0); + assert.equal(balance.toNumber(), 0); + }); + }); + + describe('Withdraw Poly', async () => { + it('Should successfully withdraw the poly', async () => { + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei('20000', 'ether'), { from: account_temp })); + }); + + it('Should successfully withdraw the poly', async () => { + let balanceBefore = await I_PolyToken.balanceOf(token_owner); + await I_SecurityToken.withdrawPoly(web3.utils.toWei('20000', 'ether'), { from: token_owner }); + let balanceAfter = await I_PolyToken.balanceOf(token_owner); + assert.equal( + BigNumber(balanceAfter) + .sub(BigNumber(balanceBefore)) + .toNumber(), + web3.utils.toWei('20000', 'ether') + ); + }); + + it('Should successfully withdraw the poly', async () => { + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei('10', 'ether'), { from: token_owner })); + }); + }); + + describe('Force Transfer', async () => { + it('Should fail to forceTransfer because not approved controller', async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei('10', 'ether'), 'reason', { + from: account_investor1 + }) + ); + }); + + it('Should fail to forceTransfer because insufficient balance', async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei('10', 'ether'), 'reason', { + from: account_controller + }) + ); + }); + + it('Should fail to forceTransfer because recipient is zero address', async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei('10', 'ether'), 'reason', { + from: account_controller + }) + ); + }); + + it('Should successfully forceTransfer', async () => { + let sender = account_investor1; + let receiver = account_investor2; + + let start_investorCount = await I_SecurityToken.investorCount.call(); + let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); + let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); + + let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei('10', 'ether'), 'reason', { + from: account_controller + }); + + let end_investorCount = await I_SecurityToken.investorCount.call(); + let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); + let end_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); + + assert.equal(start_investorCount.add(1).toNumber(), end_investorCount.toNumber(), 'Investor count not changed'); + assert.equal(start_balInv1.sub(web3.utils.toWei('10', 'ether')).toNumber(), end_balInv1.toNumber(), 'Investor balance not changed'); + assert.equal(start_balInv2.add(web3.utils.toWei('10', 'ether')).toNumber(), end_balInv2.toNumber(), 'Investor balance not changed'); + console.log(tx.logs[0].args); + console.log(tx.logs[1].args); + assert.equal(account_controller, tx.logs[0].args._controller, 'Event not emitted as expected'); + assert.equal(account_investor1, tx.logs[0].args._from, 'Event not emitted as expected'); + assert.equal(account_investor2, tx.logs[0].args._to, 'Event not emitted as expected'); + assert.equal(web3.utils.toWei('10', 'ether'), tx.logs[0].args._value, 'Event not emitted as expected'); + console.log(tx.logs[0].args._verifyTransfer); + assert.equal(false, tx.logs[0].args._verifyTransfer, 'Event not emitted as expected'); + assert.equal('reason', web3.utils.hexToUtf8(tx.logs[0].args._data), 'Event not emitted as expected'); + + assert.equal(account_investor1, tx.logs[1].args.from, 'Event not emitted as expected'); + assert.equal(account_investor2, tx.logs[1].args.to, 'Event not emitted as expected'); + assert.equal(web3.utils.toWei('10', 'ether'), tx.logs[1].args.value, 'Event not emitted as expected'); + }); + + it('Should fail to freeze controller functionality because not owner', async () => { + await catchRevert(I_SecurityToken.disableController({ from: account_investor1 })); + }); + + it('Should fail to freeze controller functionality because disableControllerAllowed not activated', async () => { + await catchRevert(I_SecurityToken.disableController({ from: token_owner })); + }); + + it('Should successfully freeze controller functionality', async () => { + let tx1 = await I_FeatureRegistry.setFeatureStatus('disableControllerAllowed', true, { from: account_polymath }); + + // check event + assert.equal('disableControllerAllowed', tx1.logs[0].args._nameKey, 'Event not emitted as expected'); + assert.equal(true, tx1.logs[0].args._newStatus, 'Event not emitted as expected'); + + let tx2 = await I_SecurityToken.disableController({ from: token_owner }); + + // check state + assert.equal(address_zero, await I_SecurityToken.controller.call(), 'State not changed'); + assert.equal(true, await I_SecurityToken.controllerDisabled.call(), 'State not changed'); + }); + + it('Should fail to freeze controller functionality because already frozen', async () => { + await catchRevert(I_SecurityToken.disableController({ from: token_owner })); + }); + + it('Should fail to set controller because controller functionality frozen', async () => { + await catchRevert(I_SecurityToken.setController(account_controller, { from: token_owner })); + }); + + it('Should fail to forceTransfer because controller functionality frozen', async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei('10', 'ether'), 'reason', { + from: account_controller + }) + ); + }); }); +}); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 1584e7806..407c59ec9 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); const USDTieredSTOProxyFactory = artifacts.require('./USDTieredSTOProxyFactory'); const USDTieredSTO = artifacts.require('./USDTieredSTO.sol'); @@ -24,88 +24,88 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('USDTieredSTO', accounts => { - // Accounts Variable declaration - let POLYMATH; - let ISSUER; - let WALLET; - let RESERVEWALLET; - let INVESTOR1; - let INVESTOR2; - let INVESTOR3; - let INVESTOR4; - let ACCREDITED1; - let ACCREDITED2; - let NONACCREDITED1; - let NONACCREDITED2; - let ETH = 0; - let POLY = 1; - let DAI = 2; - - let MESSAGE = "Transaction Should Fail!"; - const GAS_PRICE = 0; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_USDTieredSTOProxyFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_USDTieredSTOFactory; - let I_USDOracle; - let I_POLYOracle; - let I_STFactory; - let I_SecurityToken; - let I_STRProxied; - let I_MRProxied; - let I_USDTieredSTO_Array = []; - let I_PolyToken; - let I_DaiToken; - let I_PolymathRegistry; - - // SecurityToken Details for funds raise Type ETH - const NAME = "Team"; - const SYMBOL = "SAP"; - const TOKENDETAILS = "This is equity type of issuance"; - const DECIMALS = 18; - - // Module key - const TMKEY = 2; - const STOKEY = 3; - - // Initial fee for ticker registry and security token registry - const REGFEE = web3.utils.toWei("250"); - const STOSetupCost = 0; - - // MockOracle USD prices - const USDETH = BigNumber(500).mul(10**18); // 500 USD/ETH - const USDPOLY = BigNumber(25).mul(10**16); // 0.25 USD/POLY - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - // STO Configuration Arrays - let _startTime = []; - let _endTime = []; - let _ratePerTier = []; - let _ratePerTierDiscountPoly = []; - let _tokensPerTierTotal = []; - let _tokensPerTierDiscountPoly = []; - let _nonAccreditedLimitUSD = []; - let _minimumInvestmentUSD = []; - let _fundRaiseTypes = []; - let _wallet = []; - let _reserveWallet = []; - let _usdToken = []; - - /* function configure( + // Accounts Variable declaration + let POLYMATH; + let ISSUER; + let WALLET; + let RESERVEWALLET; + let INVESTOR1; + let INVESTOR2; + let INVESTOR3; + let INVESTOR4; + let ACCREDITED1; + let ACCREDITED2; + let NONACCREDITED1; + let NONACCREDITED2; + let ETH = 0; + let POLY = 1; + let DAI = 2; + + let MESSAGE = 'Transaction Should Fail!'; + const GAS_PRICE = 0; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_USDTieredSTOProxyFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_USDTieredSTOFactory; + let I_USDOracle; + let I_POLYOracle; + let I_STFactory; + let I_SecurityToken; + let I_STRProxied; + let I_MRProxied; + let I_USDTieredSTO_Array = []; + let I_PolyToken; + let I_DaiToken; + let I_PolymathRegistry; + + // SecurityToken Details for funds raise Type ETH + const NAME = 'Team'; + const SYMBOL = 'SAP'; + const TOKENDETAILS = 'This is equity type of issuance'; + const DECIMALS = 18; + + // Module key + const TMKEY = 2; + const STOKEY = 3; + + // Initial fee for ticker registry and security token registry + const REGFEE = web3.utils.toWei('250'); + const STOSetupCost = 0; + + // MockOracle USD prices + const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH + const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + // STO Configuration Arrays + let _startTime = []; + let _endTime = []; + let _ratePerTier = []; + let _ratePerTierDiscountPoly = []; + let _tokensPerTierTotal = []; + let _tokensPerTierDiscountPoly = []; + let _nonAccreditedLimitUSD = []; + let _minimumInvestmentUSD = []; + let _fundRaiseTypes = []; + let _wallet = []; + let _reserveWallet = []; + let _usdToken = []; + + /* function configure( uint256 _startTime, uint256 _endTime, uint256[] _ratePerTier, @@ -119,210 +119,222 @@ contract('USDTieredSTO', accounts => { address _reserveWallet, address _usdToken ) */ - const functionSignature = { - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_startTime' - },{ - type: 'uint256', - name: '_endTime' - },{ - type: 'uint256[]', - name: '_ratePerTier' - },{ - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - },{ - type: 'uint256[]', - name: '_tokensPerTier' - },{ - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - },{ - type: 'uint256', - name: '_nonAccreditedLimitUSD' - },{ - type: 'uint256', - name: '_minimumInvestmentUSD' - },{ - type: 'uint8[]', - name: '_fundRaiseTypes' - },{ - type: 'address', - name: '_wallet' - },{ - type: 'address', - name: '_reserveWallet' - },{ - type: 'address', - name: '_usdToken' - }] - }; - - async function convert(_stoID, _tier, _discount, _currencyFrom, _currencyTo, _amount) { - let USDTOKEN; - if (_discount) - USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTierDiscountPoly.call(_tier); - else - USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTier.call(_tier); - if (_currencyFrom == "TOKEN") { - let tokenToUSD = _amount.div(10**18).mul(USDTOKEN.div(10**18)).mul(10**18); // TOKEN * USD/TOKEN = USD - if (_currencyTo == "USD") - return tokenToUSD; - if (_currencyTo == "ETH") { - return await I_USDTieredSTO_Array[_stoID].convertFromUSD(ETH, tokenToUSD); - } else if (_currencyTo == "POLY") { - return await I_USDTieredSTO_Array[_stoID].convertFromUSD(POLY, tokenToUSD); - } - } - if (_currencyFrom == "USD") { - if (_currencyTo == "TOKEN") - return _amount.div(USDTOKEN).mul(10**18); // USD / USD/TOKEN = TOKEN - if (_currencyTo == "ETH" || _currencyTo == "POLY") - return await I_USDTieredSTO_Array[_stoID].convertFromUSD((_currencyTo == "ETH" ? ETH : POLY), _amount); - } - if (_currencyFrom == "ETH" || _currencyFrom == "POLY") { - let ethToUSD = await I_USDTieredSTO_Array[_stoID].convertToUSD((_currencyTo == "ETH" ? ETH : POLY), _amount); - if (_currencyTo == "USD") - return ethToUSD; - if (_currencyTo == "TOKEN") - return ethToUSD.div(USDTOKEN).mul(10**18); // USD / USD/TOKEN = TOKEN - } - return 0; + const functionSignature = { + name: 'configure', + type: 'function', + inputs: [ + { + type: 'uint256', + name: '_startTime' + }, + { + type: 'uint256', + name: '_endTime' + }, + { + type: 'uint256[]', + name: '_ratePerTier' + }, + { + type: 'uint256[]', + name: '_ratePerTierDiscountPoly' + }, + { + type: 'uint256[]', + name: '_tokensPerTier' + }, + { + type: 'uint256[]', + name: '_tokensPerTierDiscountPoly' + }, + { + type: 'uint256', + name: '_nonAccreditedLimitUSD' + }, + { + type: 'uint256', + name: '_minimumInvestmentUSD' + }, + { + type: 'uint8[]', + name: '_fundRaiseTypes' + }, + { + type: 'address', + name: '_wallet' + }, + { + type: 'address', + name: '_reserveWallet' + }, + { + type: 'address', + name: '_usdToken' + } + ] + }; + + async function convert(_stoID, _tier, _discount, _currencyFrom, _currencyTo, _amount) { + let USDTOKEN; + if (_discount) USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTierDiscountPoly.call(_tier); + else USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTier.call(_tier); + if (_currencyFrom == 'TOKEN') { + let tokenToUSD = _amount + .div(10 ** 18) + .mul(USDTOKEN.div(10 ** 18)) + .mul(10 ** 18); // TOKEN * USD/TOKEN = USD + if (_currencyTo == 'USD') return tokenToUSD; + if (_currencyTo == 'ETH') { + return await I_USDTieredSTO_Array[_stoID].convertFromUSD(ETH, tokenToUSD); + } else if (_currencyTo == 'POLY') { + return await I_USDTieredSTO_Array[_stoID].convertFromUSD(POLY, tokenToUSD); + } } + if (_currencyFrom == 'USD') { + if (_currencyTo == 'TOKEN') return _amount.div(USDTOKEN).mul(10 ** 18); // USD / USD/TOKEN = TOKEN + if (_currencyTo == 'ETH' || _currencyTo == 'POLY') + return await I_USDTieredSTO_Array[_stoID].convertFromUSD(_currencyTo == 'ETH' ? ETH : POLY, _amount); + } + if (_currencyFrom == 'ETH' || _currencyFrom == 'POLY') { + let ethToUSD = await I_USDTieredSTO_Array[_stoID].convertToUSD(_currencyTo == 'ETH' ? ETH : POLY, _amount); + if (_currencyTo == 'USD') return ethToUSD; + if (_currencyTo == 'TOKEN') return ethToUSD.div(USDTOKEN).mul(10 ** 18); // USD / USD/TOKEN = TOKEN + } + return 0; + } + + before(async () => { + // Accounts setup + POLYMATH = accounts[0]; + ISSUER = accounts[1]; + WALLET = accounts[2]; + RESERVEWALLET = WALLET; + ACCREDITED1 = accounts[3]; + ACCREDITED2 = accounts[4]; + NONACCREDITED1 = accounts[5]; + NONACCREDITED2 = accounts[6]; + INVESTOR1 = accounts[7]; + INVESTOR2 = accounts[8]; + INVESTOR3 = accounts[9]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + I_DaiToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: POLYMATH + }); - before(async() => { - // Accounts setup - POLYMATH = accounts[0]; - ISSUER = accounts[1]; - WALLET = accounts[2]; - RESERVEWALLET = WALLET; - ACCREDITED1 = accounts[3]; - ACCREDITED2 = accounts[4]; - NONACCREDITED1 = accounts[5]; - NONACCREDITED2 = accounts[6]; - INVESTOR1 = accounts[7]; - INVESTOR2 = accounts[8]; - INVESTOR3 = accounts[9]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), ISSUER); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: POLYMATH - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 3: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the proxy - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - - // STEP 6: Deploy the USDTieredSTOFactory - - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: ISSUER }); - - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "USDTieredSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 9: Deploy the SecurityTokenRegistry contract + // STEP 3: Deploy the ModuleRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + // STEP 3: Deploy the GeneralTransferManagerFactory - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: POLYMATH}); - await I_MRProxied.updateFromRegistry({from: POLYMATH}); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); + // STEP 4: Deploy the GeneralDelegateManagerFactory - // STEP 7: Register the Modules with the ModuleRegistry contract + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); + // STEP 5: Deploy the proxy + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + // STEP 6: Deploy the USDTieredSTOFactory - // 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 }); - await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { + from: ISSUER + }); - // Printing all the contract addresses - console.log(` + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'USDTieredSTOFactory contract was not deployed' + ); + + // Step 8: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + + // Step 9: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + REGFEE, + REGFEE, + I_PolyToken.address, + POLYMATH + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); + await I_MRProxied.updateFromRegistry({ from: POLYMATH }); + + // STEP 7: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + + // 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 }); + await I_PolymathRegistry.changeAddress('PolyUsdOracle', I_POLYOracle.address, { from: POLYMATH }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -340,1703 +352,2485 @@ contract('USDTieredSTO', accounts => { USDTieredSTOProxyFactory: ${I_USDTieredSTOProxyFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from: ISSUER }); + assert.equal(tx.logs[0].args._owner, ISSUER); + assert.equal(tx.logs[0].args._ticker, SYMBOL); + }); + + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); + assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), TMKEY); + assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); + }); + + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(TMKEY, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + }); + + describe('Test sto deployment', async () => { + it('Should successfully attach the first STO module to the security token', async () => { + let stoId = 0; // No discount + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] + _tokensPerTierTotal.push([BigNumber(100000000).mul(BigNumber(10 ** 18)), BigNumber(200000000).mul(BigNumber(10 ** 18))]); // [ 100m Token, 200m Token ] + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0)]); // [ 0, 0 ] + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); // 10k USD + _minimumInvestmentUSD.push(BigNumber(5 * 10 ** 18)); // 5 USD + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], 'Incorrect _startTime in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], 'Incorrect _endTime in config'); + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), + _ratePerTier[stoId][i].toNumber(), + 'Incorrect _ratePerTier in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), + _ratePerTierDiscountPoly[stoId][i].toNumber(), + 'Incorrect _ratePerTierDiscountPoly in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), + _tokensPerTierTotal[stoId][i].toNumber(), + 'Incorrect _tokensPerTierTotal in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), + _tokensPerTierDiscountPoly[stoId][i].toNumber(), + 'Incorrect _tokensPerTierDiscountPoly in config' + ); + } + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + _nonAccreditedLimitUSD[stoId].toNumber(), + 'Incorrect _nonAccreditedLimitUSD in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + _minimumInvestmentUSD[stoId].toNumber(), + 'Incorrect _minimumInvestmentUSD in config' + ); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], 'Incorrect _wallet in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(), _reserveWallet[stoId], 'Incorrect _reserveWallet in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(), _usdToken[stoId], 'Incorrect _usdToken in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, 'Incorrect number of tiers'); + assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, 'Incorrect number of permissions'); + }); + + it('Should successfully attach the second STO module to the security token', async () => { + let stoId = 1; // No discount + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([ + BigNumber(10 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16) + ]); + _ratePerTierDiscountPoly.push([ + BigNumber(10 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16) + ]); + _tokensPerTierTotal.push([ + BigNumber(5 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(50 * 10 ** 18) + ]); + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0)]); + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); + _minimumInvestmentUSD.push(BigNumber(0)); + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], 'Incorrect _startTime in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], 'Incorrect _endTime in config'); + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), + _ratePerTier[stoId][i].toNumber(), + 'Incorrect _ratePerTier in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), + _ratePerTierDiscountPoly[stoId][i].toNumber(), + 'Incorrect _ratePerTierDiscountPoly in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), + _tokensPerTierTotal[stoId][i].toNumber(), + 'Incorrect _tokensPerTierTotal in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), + _tokensPerTierDiscountPoly[stoId][i].toNumber(), + 'Incorrect _tokensPerTierDiscountPoly in config' + ); + } + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + _nonAccreditedLimitUSD[stoId].toNumber(), + 'Incorrect _nonAccreditedLimitUSD in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + _minimumInvestmentUSD[stoId].toNumber(), + 'Incorrect _minimumInvestmentUSD in config' + ); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], 'Incorrect _wallet in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(), _reserveWallet[stoId], 'Incorrect _reserveWallet in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(), _usdToken[stoId], 'Incorrect _usdToken in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, 'Incorrect number of tiers'); + assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, 'Incorrect number of permissions'); + }); + + it('Should successfully attach the third STO module to the security token', async () => { + let stoId = 2; // Poly discount + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([BigNumber(1 * 10 ** 18), BigNumber(1.5 * 10 ** 18)]); // [ 1 USD/Token, 1.5 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(0.5 * 10 ** 18), BigNumber(1 * 10 ** 18)]); // [ 0.5 USD/Token, 1.5 USD/Token ] + _tokensPerTierTotal.push([BigNumber(100 * 10 ** 18), BigNumber(50 * 10 ** 18)]); // [ 100 Token, 50 Token ] + _tokensPerTierDiscountPoly.push([BigNumber(100 * 10 ** 18), BigNumber(25 * 10 ** 18)]); // [ 100 Token, 25 Token ] + _nonAccreditedLimitUSD.push(BigNumber(25 * 10 ** 18)); // [ 25 USD ] + _minimumInvestmentUSD.push(BigNumber(5)); + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + }); + + it('Should successfully attach the fourth STO module to the security token', async () => { + let stoId = 3; + + _startTime.push(latestTime() + duration.days(0.1)); + _endTime.push(_startTime[stoId] + duration.days(0.1)); + _ratePerTier.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); + _ratePerTierDiscountPoly.push([BigNumber(10 * 10 ** 16), BigNumber(12 * 10 ** 16)]); + _tokensPerTierTotal.push([BigNumber(100 * 10 ** 18), BigNumber(200 * 10 ** 18)]); + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(50 * 10 ** 18)]); + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); + _minimumInvestmentUSD.push(BigNumber(0)); + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + }); + + it('Should fail because rates and tier array of different length', async () => { + let stoId = 0; + + let ratePerTier = [10]; + let ratePerTierDiscountPoly = [10]; + let tokensPerTierTotal = [10]; + let tokensPerTierDiscountPoly = [10]; + let config = [ + [ + _startTime[stoId], + _endTime[stoId], + ratePerTier, + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ], + [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + ratePerTierDiscountPoly, + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ], + [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + tokensPerTierTotal, + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ], + [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + tokensPerTierDiscountPoly, + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ] + ]; + for (var i = 0; i < config.length; i++) { + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + } + }); + + it('Should fail because rate of token should be greater than 0', async () => { + let stoId = 0; + + let ratePerTier = [BigNumber(10 * 10 ** 16), BigNumber(0)]; + let config = [ + _startTime[stoId], + _endTime[stoId], + ratePerTier, + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it('Should fail because Zero address is not permitted for wallet', async () => { + let stoId = 0; + + let wallet = '0x0000000000000000000000000000000000000000'; + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + wallet, + _reserveWallet[stoId], + _usdToken[stoId] + ]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it('Should fail because Zero address is not permitted for reserveWallet', async () => { + let stoId = 0; + + let reserveWallet = '0x0000000000000000000000000000000000000000'; + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + reserveWallet + ]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it('Should fail because end time before start time', async () => { + let stoId = 0; + + let startTime = latestTime() + duration.days(35); + let endTime = latestTime() + duration.days(1); + let config = [ + startTime, + endTime, + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it('Should fail because start time is in the past', async () => { + let stoId = 0; + + let startTime = latestTime() - duration.days(35); + let endTime = startTime + duration.days(50); + let config = [ + startTime, + endTime, + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + }); + + describe('Test modifying configuration', async () => { + it('Should successfully change config before startTime - funding', async () => { + let stoId = 3; + await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), true, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), false, "STO Configuration doesn't set as expected"); + + await I_USDTieredSTO_Array[stoId].modifyFunding([1], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), false, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), true, "STO Configuration doesn't set as expected"); + + await I_USDTieredSTO_Array[stoId].modifyFunding([0, 1], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), true, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), true, "STO Configuration doesn't set as expected"); + }); + + it('Should successfully change config before startTime - limits and tiers, times, addresses', async () => { + let stoId = 3; + + await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1 * 10 ** 18), BigNumber(15 * 10 ** 18), { from: ISSUER }); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + BigNumber(15 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + BigNumber(1 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + + await I_USDTieredSTO_Array[stoId].modifyTiers( + [BigNumber(15 * 10 ** 18)], + [BigNumber(13 * 10 ** 18)], + [BigNumber(15 * 10 ** 20)], + [BigNumber(15 * 10 ** 20)], + { from: ISSUER } + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(), + BigNumber(15 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(), + BigNumber(13 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0), + BigNumber(15 * 10 ** 20).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0), + BigNumber(15 * 10 ** 20).toNumber(), + "STO Configuration doesn't set as expected" + ); + + let tempTime1 = latestTime() + duration.days(0.1); + let tempTime2 = latestTime() + duration.days(0.2); + + await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), tempTime1, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), tempTime2, "STO Configuration doesn't set as expected"); + + await I_USDTieredSTO_Array[stoId].modifyAddresses( + '0x0000000000000000000000000400000000000000', + '0x0000000000000000000003000000000000000000', + '0x0000000000000000000000000000000000000000', + { from: ISSUER } + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].wallet.call(), + '0x0000000000000000000000000400000000000000', + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].reserveWallet.call(), + '0x0000000000000000000003000000000000000000', + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].usdToken.call(), + '0x0000000000000000000000000000000000000000', + "STO Configuration doesn't set as expected" + ); + }); + + it('Should fail to change config after endTime', async () => { + let stoId = 3; + + let snapId = await takeSnapshot(); + await increaseTime(duration.days(1)); + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0, 1], { from: ISSUER })); + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15 * 10 ** 18), BigNumber(1 * 10 ** 18), { from: ISSUER })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].modifyTiers( + [BigNumber(15 * 10 ** 18)], + [BigNumber(13 * 10 ** 18)], + [BigNumber(15 * 10 ** 20)], + [BigNumber(15 * 10 ** 20)], + { from: ISSUER } + ) + ); + + let tempTime1 = latestTime(); + let tempTime2 = latestTime() + duration.days(3); + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].modifyAddresses( + '0x0000000000000000000000000400000000000000', + '0x0000000000000000000003000000000000000000', + I_DaiToken.address, + { from: ISSUER } + ) + ); + + await revertToSnapshot(snapId); + }); + }); + + describe('Test buying failure conditions', async () => { + it('should fail if before STO start time', async () => { + let stoId = 0; + let snapId = await takeSnapshot(); + + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, 'STO is not showing correct status'); + + // Whitelist + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + + // // Advance time to after STO start + // await increaseTime(duration.days(3)); + + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + // Prep for investments + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); + + // NONACCREDITED ETH + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + }); + + it('should fail and revert despite oracle price change when NONACCREDITED cap reached', async () => { + let stoId = 0; + let tierId; + + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY + + let investment_USD = BigNumber(web3.utils.toWei('50')); // USD + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); + + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); + + it('should successfully buy across tiers for NONACCREDITED ETH', async () => { + let stoId = 1; + let startTier = 0; + let endTier = 1; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); + + let delta_Token = BigNumber(5).mul(10 ** 18); + let ethTier0 = await convert(stoId, startTier, false, 'TOKEN', 'ETH', delta_Token); + let ethTier1 = await convert(stoId, endTier, false, 'TOKEN', 'ETH', delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + 'Wallet ETH Balance not changed as expected' + ); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); + }); + + it('should successfully buy across tiers for NONACCREDITED POLY', async () => { + let stoId = 1; + let startTier = 1; + let endTier = 2; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); + + let delta_Token = BigNumber(5).mul(10 ** 18); // Token + let polyTier0 = await convert(stoId, startTier, false, 'TOKEN', 'POLY', delta_Token); + let polyTier1 = await convert(stoId, endTier, false, 'TOKEN', 'POLY', delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + 'Wallet POLY Balance not changed as expected' + ); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); + }); + + it('should successfully buy across tiers for ACCREDITED ETH', async () => { + let stoId = 1; + let startTier = 2; + let endTier = 3; + + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); + + let delta_Token = BigNumber(5).mul(10 ** 18); // Token + let ethTier0 = await convert(stoId, startTier, false, 'TOKEN', 'ETH', delta_Token); + let ethTier1 = await convert(stoId, endTier, false, 'TOKEN', 'ETH', delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { + from: ACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + 'Wallet ETH Balance not changed as expected' + ); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); + }); + + it('should successfully buy across tiers for ACCREDITED DAI', async () => { + let stoId = 1; + let startTier = 3; + let endTier = 4; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); + + let delta_Token = BigNumber(5).mul(10 ** 18); // Token + let daiTier0 = await convert(stoId, startTier, false, 'TOKEN', 'USD', delta_Token); + let daiTier1 = await convert(stoId, endTier, false, 'TOKEN', 'USD', delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_DAI = daiTier0.add(daiTier1); + + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithUSD: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); + assert.equal( + final_InvestorDAIBal.toNumber(), + init_InvestorDAIBal.sub(investment_DAI).toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); + assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), 'Raised DAI not changed as expected'); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); + assert.equal( + final_WalletDAIBal.toNumber(), + init_WalletDAIBal.add(investment_DAI).toNumber(), + 'Wallet POLY Balance not changed as expected' + ); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); + }); + + it('should successfully buy across tiers for ACCREDITED POLY', async () => { + let stoId = 1; + let startTier = 4; + let endTier = 5; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); + + let delta_Token = BigNumber(5).mul(10 ** 18); // Token + let polyTier0 = await convert(stoId, startTier, false, 'TOKEN', 'POLY', delta_Token); + let polyTier1 = await convert(stoId, endTier, false, 'TOKEN', 'POLY', delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + 'Wallet POLY Balance not changed as expected' + ); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); }); - describe("Generate the SecurityToken", async() => { + it('should buy out the rest of the sto', async () => { + let stoId = 1; + let tierId = 5; + + let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); + console.log(minted.toNumber() + ':' + _tokensPerTierTotal[stoId][tierId]); + let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); + console.log(investment_Token.toNumber()); + let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + let tx = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + console.log(' Gas buyWithETH: '.grey + tx.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + // assert.equal((await I_USDTieredSTO_Array[1].getTokensMinted()).toNumber(), _tokensPerTierTotal[1].reduce((a, b) => a + b, 0).toNumber(), "STO Token Sold not changed as expected"); + }); + + it('should fail and revert when all tiers sold out', async () => { + let stoId = 1; + let tierId = 4; + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); + let investment_DAI = investment_USD; + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, 'STO is not showing correct status'); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Buy with DAI NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Buy with ETH ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with DAI ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + }); + + it('should fail and revert when all tiers sold out despite oracle price change', async () => { + let stoId = 1; + let tierId = 4; + + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY + + let investment_USD = BigNumber(web3.utils.toWei('50')); // USD + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); + await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: ACCREDITED1 }); + + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from : ISSUER }); - assert.equal(tx.logs[0].args._owner, ISSUER); - assert.equal(tx.logs[0].args._ticker, SYMBOL); - }); + // Buy with POLY NONACCREDITED - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); - assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + // Buy with ETH ACCREDITED - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), TMKEY); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); - }); + // Buy with POLY ACCREDITED - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(TMKEY, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); - }); + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Buy with ETH ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); + }); + + describe('Buy Tokens with POLY discount', async () => { + it('should successfully buy using fallback at tier 0 for NONACCREDITED1', async () => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await web3.eth.sendTransaction({ + from: NONACCREDITED1, + to: I_USDTieredSTO_Array[stoId].address, + value: investment_ETH, + gasPrice: GAS_PRICE, + gas: 1000000 + }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); + console.log(' Gas fallback purchase: '.grey + tx1.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), 'Raised USD not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + 'Wallet ETH Balance not changed as expected' + ); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); + + // Additional checks on getters + assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, 'Investor count not changed as expected'); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), + investment_Token.toNumber(), + 'getTokensSold not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), + investment_Token.toNumber(), + 'getTokensMinted not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), + investment_Token.toNumber(), + 'getTokensSoldForETH not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), + 0, + 'getTokensSoldForPOLY not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), + investment_USD.toNumber(), + 'investorInvestedUSD not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), + investment_ETH.toNumber(), + 'investorInvestedETH not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), + 0, + 'investorInvestedPOLY not changed as expected' + ); + }); + + it('should successfully buy using buyWithETH at tier 0 for NONACCREDITED1', async () => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + 'Wallet ETH Balance not changed as expected' + ); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); + }); + + it('should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1', async () => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, true, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', investment_Token); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + 'Wallet POLY Balance not changed as expected' + ); }); - describe("Test sto deployment", async() => { - - it("Should successfully attach the first STO module to the security token", async () => { - let stoId = 0; // No discount - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] - _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(15*10**16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] - _tokensPerTierTotal.push([BigNumber(100000000).mul(BigNumber(10**18)), BigNumber(200000000).mul(BigNumber(10**18))]); // [ 100m Token, 200m Token ] - _tokensPerTierDiscountPoly.push([BigNumber(0),BigNumber(0)]); // [ 0, 0 ] - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); // 10k USD - _minimumInvestmentUSD.push(BigNumber(5*10**18)); // 5 USD - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - - assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); - } - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].usdToken.call()), _usdToken[stoId], "Incorrect _usdToken in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].getNumberOfTiers()), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); - assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); - }); - - it("Should successfully attach the second STO module to the security token", async () => { - let stoId = 1; // No discount - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16)]); - _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16)]); - _tokensPerTierTotal.push([BigNumber(5*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(50*10**18)]); - _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0)]); - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); - _minimumInvestmentUSD.push(BigNumber(0)); - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - - assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); - } - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].usdToken.call()), _usdToken[stoId], "Incorrect _usdToken in config"); - assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); - assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); - }); - - it("Should successfully attach the third STO module to the security token", async () => { - let stoId = 2; // Poly discount - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(1*10**18), BigNumber(1.5*10**18)]); // [ 1 USD/Token, 1.5 USD/Token ] - _ratePerTierDiscountPoly.push([BigNumber(0.5*10**18), BigNumber(1*10**18)]); // [ 0.5 USD/Token, 1.5 USD/Token ] - _tokensPerTierTotal.push([BigNumber(100*10**18), BigNumber(50*10**18)]); // [ 100 Token, 50 Token ] - _tokensPerTierDiscountPoly.push([BigNumber(100*10**18),BigNumber(25*10**18)]); // [ 100 Token, 25 Token ] - _nonAccreditedLimitUSD.push(BigNumber(25*10**18)); // [ 25 USD ] - _minimumInvestmentUSD.push(BigNumber(5)); - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address) - - let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - }); - - it("Should successfully attach the fourth STO module to the security token", async () => { - let stoId = 3; - - _startTime.push(latestTime()+ duration.days(0.1)); - _endTime.push(_startTime[stoId] + duration.days(0.1)); - _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16)]); - _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(12*10**16)]); - _tokensPerTierTotal.push([BigNumber(100*10**18), BigNumber(200*10**18)]); - _tokensPerTierDiscountPoly.push([BigNumber(0),BigNumber(50*10**18)]); - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); - _minimumInvestmentUSD.push(BigNumber(0)); - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - }); - - it("Should fail because rates and tier array of different length", async() => { - let stoId = 0; - - let ratePerTier = [10]; - let ratePerTierDiscountPoly = [10]; - let tokensPerTierTotal = [10]; - let tokensPerTierDiscountPoly = [10]; - let config = [ - [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], - [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], ratePerTierDiscountPoly, _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], - [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], tokensPerTierTotal, _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], - [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], tokensPerTierDiscountPoly, _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]] - ]; - for (var i = 0; i < config.length; i++) { - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - } - }); - - it("Should fail because rate of token should be greater than 0", async() => { - let stoId = 0; - - let ratePerTier = [BigNumber(10*10**16), BigNumber(0)]; - let config = [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it("Should fail because Zero address is not permitted for wallet", async() => { - let stoId = 0; - - let wallet = "0x0000000000000000000000000000000000000000"; - let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], wallet, _reserveWallet[stoId], _usdToken[stoId]]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it("Should fail because Zero address is not permitted for reserveWallet", async() => { - let stoId = 0; - - let reserveWallet = "0x0000000000000000000000000000000000000000"; - let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], reserveWallet]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it("Should fail because end time before start time", async() => { - let stoId = 0; - - let startTime = latestTime() + duration.days(35); - let endTime = latestTime() + duration.days(1); - let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it("Should fail because start time is in the past", async() => { - let stoId = 0; - - let startTime = latestTime() - duration.days(35); - let endTime = startTime + duration.days(50); - let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); + it('should successfully buy using fallback at tier 0 for ACCREDITED1', async () => { + let stoId = 2; + let tierId = 0; + + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await web3.eth.sendTransaction({ + from: ACCREDITED1, + to: I_USDTieredSTO_Array[stoId].address, + value: investment_ETH, + gasPrice: GAS_PRICE, + gas: 1000000 + }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); + console.log(' Gas fallback purchase: '.grey + tx1.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + 'Wallet ETH Balance not changed as expected' + ); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); }); - describe("Test modifying configuration", async() => { + it('should successfully buy using buyWithETH at tier 0 for ACCREDITED1', async () => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { + from: ACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + 'Wallet ETH Balance not changed as expected' + ); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); + }); - it("Should successfully change config before startTime - funding", async() => { - let stoId = 3; - await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),false,"STO Configuration doesn't set as expected"); + it('should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1', async () => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, true, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', investment_Token); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + + // Additional checks on getters + let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_getTokensMinted = await I_USDTieredSTO_Array[stoId].getTokensMinted(); + let init_getTokensSoldForETH = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH); + let init_getTokensSoldForPOLY = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY); + let init_investorInvestedUSD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1); + let init_investorInvestedETH = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH); + let init_investorInvestedPOLY = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + 'Wallet POLY Balance not changed as expected' + ); + + // Additional checks on getters + assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, 'Investor count not changed as expected'); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), + init_getTokensSold.add(investment_Token).toNumber(), + 'getTokensSold not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), + init_getTokensMinted.add(investment_Token).toNumber(), + 'getTokensMinted not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), + init_getTokensSoldForETH.toNumber(), + 'getTokensSoldForETH not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), + init_getTokensSoldForPOLY.add(investment_Token).toNumber(), + 'getTokensSoldForPOLY not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), + init_investorInvestedUSD.add(investment_USD).toNumber(), + 'investorInvestedUSD not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), + init_investorInvestedETH.toNumber(), + 'investorInvestedETH not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), + init_investorInvestedPOLY.add(investment_POLY).toNumber(), + 'investorInvestedPOLY not changed as expected' + ); + }); - await I_USDTieredSTO_Array[stoId].modifyFunding([1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),false,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); + it('should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap', async () => { + let stoId = 2; + let tierId = 0; + + let investment_USD = _nonAccreditedLimitUSD[stoId]; + let investment_Token = await convert(stoId, tierId, true, 'USD', 'TOKEN', investment_USD); + let investment_ETH = await convert(stoId, tierId, true, 'USD', 'ETH', investment_USD); + let investment_POLY = await convert(stoId, tierId, true, 'USD', 'POLY', investment_USD); + + let refund_USD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); + let refund_Token = await convert(stoId, tierId, true, 'USD', 'TOKEN', refund_USD); + let refund_ETH = await convert(stoId, tierId, true, 'USD', 'ETH', refund_USD); + let refund_POLY = await convert(stoId, tierId, true, 'USD', 'POLY', refund_USD); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + 'Token Supply not changed as expected' + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal + .sub(investment_POLY) + .add(refund_POLY) + .toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + 'Raised POLY not changed as expected' + ); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + 'Wallet POLY Balance not changed as expected' + ); + }); - await I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); + it('should fail and revert when NONACCREDITED cap reached', async () => { + let stoId = 2; + let tierId = 0; + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, true, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', investment_Token); - }); + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - it("Should successfully change config before startTime - limits and tiers, times, addresses", async() => { - let stoId = 3; + // Buy with ETH NONACCREDITED - await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1*10**18), BigNumber(15*10**18), { from: ISSUER }); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(),BigNumber(1*10**18).toNumber(),"STO Configuration doesn't set as expected"); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + }); - await I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER }); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(),BigNumber(13*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); + it('should fail and revert despite oracle price change when NONACCREDITED cap reached', async () => { + let stoId = 2; + let tierId = 0; - let tempTime1 = latestTime() + duration.days(0.1); - let tempTime2 = latestTime() + duration.days(0.2); + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(),tempTime1,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(),tempTime2,"STO Configuration doesn't set as expected"); + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); - await I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", "0x0000000000000000000000000000000000000000", { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(),"0x0000000000000000000000000400000000000000","STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(),"0x0000000000000000000003000000000000000000","STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(),"0x0000000000000000000000000000000000000000","STO Configuration doesn't set as expected"); - }); + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - it("Should fail to change config after endTime", async() => { - let stoId = 3; + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); - let snapId = await takeSnapshot(); - await increaseTime(duration.days(1)); + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER })); + // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15*10**18), BigNumber(1*10**18), { from: ISSUER })); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER })); + // Buy with POLY NONACCREDITED - let tempTime1 = latestTime(); - let tempTime2 = latestTime() + duration.days(3); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER })); + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", I_DaiToken.address, { from: ISSUER })); + // Buy with ETH NONACCREDITED - await revertToSnapshot(snapId); - }); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); }); - describe("Test buying failure conditions", async() => { - - it("should fail if before STO start time", async() => { - let stoId = 0; - let snapId = await takeSnapshot(); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); - - // Whitelist - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - - // // Advance time to after STO start - // await increaseTime(duration.days(3)); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - // NONACCREDITED ETH - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - }); - - it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { - let stoId = 0; - let tierId; - - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY - - let investment_USD = BigNumber(web3.utils.toWei('50')); // USD - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); - - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); - - it("should successfully buy across tiers for NONACCREDITED ETH", async() => { - let stoId = 1; - let startTier = 0; - let endTier = 1; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); - - let delta_Token = BigNumber(5).mul(10**18); - let ethTier0 = await convert(stoId, startTier, false, "TOKEN", "ETH", delta_Token); - let ethTier1 = await convert(stoId, endTier, false, "TOKEN", "ETH", delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); - }); - - it("should successfully buy across tiers for NONACCREDITED POLY", async() => { - let stoId = 1; - let startTier = 1; - let endTier = 2; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); - - let delta_Token = BigNumber(5).mul(10**18); // Token - let polyTier0 = await convert(stoId, startTier, false, "TOKEN", "POLY", delta_Token); - let polyTier1 = await convert(stoId, endTier, false, "TOKEN", "POLY", delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); - }); - - it("should successfully buy across tiers for ACCREDITED ETH", async() => { - let stoId = 1; - let startTier = 2; - let endTier = 3; - - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); - - let delta_Token = BigNumber(5).mul(10**18); // Token - let ethTier0 = await convert(stoId, startTier, false, "TOKEN", "ETH", delta_Token); - let ethTier1 = await convert(stoId, endTier, false, "TOKEN", "ETH", delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); - }); - - it("should successfully buy across tiers for ACCREDITED DAI", async() => { - - let stoId = 1; - let startTier = 3; - let endTier = 4; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); - - let delta_Token = BigNumber(5).mul(10**18); // Token - let daiTier0 = await convert(stoId, startTier, false, "TOKEN", "USD", delta_Token); - let daiTier1 = await convert(stoId, endTier, false, "TOKEN", "USD", delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_DAI = daiTier0.add(daiTier1); - - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithUSD: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), "Raised DAI not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - assert.equal(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); - - }); - - it("should successfully buy across tiers for ACCREDITED POLY", async() => { - let stoId = 1; - let startTier = 4; - let endTier = 5; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); - - let delta_Token = BigNumber(5).mul(10**18); // Token - let polyTier0 = await convert(stoId, startTier, false, "TOKEN", "POLY", delta_Token); - let polyTier1 = await convert(stoId, endTier, false, "TOKEN", "POLY", delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); - }); - - it("should buy out the rest of the sto", async() => { - let stoId = 1; - let tierId = 5; - - let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); - console.log(minted.toNumber() + ":"+ _tokensPerTierTotal[stoId][tierId]); - let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); - console.log(investment_Token.toNumber()); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - let tx = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - console.log(" Gas buyWithETH: ".grey+tx.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - // assert.equal((await I_USDTieredSTO_Array[1].getTokensMinted()).toNumber(), _tokensPerTierTotal[1].reduce((a, b) => a + b, 0).toNumber(), "STO Token Sold not changed as expected"); - }); - - it("should fail and revert when all tiers sold out", async() => { - let stoId = 1; - let tierId = 4; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - let investment_DAI = investment_USD; - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with DAI NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with DAI ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - }); - - it("should fail and revert when all tiers sold out despite oracle price change", async() => { - let stoId = 1; - let tierId = 4; - - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY - - let investment_USD = BigNumber(web3.utils.toWei('50')); // USD - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: ACCREDITED1}); - - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); + it('should successfully buy across tiers for POLY', async () => { + let stoId = 2; + let startTier = 0; + let endTier = 1; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); + + let delta_Token = BigNumber(5).mul(10 ** 18); // Token + let polyTier0 = await convert(stoId, startTier, true, 'TOKEN', 'POLY', delta_Token); + let polyTier1 = await convert(stoId, endTier, true, 'TOKEN', 'POLY', delta_Token); + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + + let tokensRemaining = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)).sub( + await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier) + ); + let prep_Token = tokensRemaining.sub(delta_Token); + let prep_POLY = await convert(stoId, startTier, true, 'TOKEN', 'POLY', prep_Token); + + await I_PolyToken.getTokens(prep_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, prep_POLY, { from: ACCREDITED1 }); + let tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, prep_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + console.log(' Gas buyWithPOLY: '.grey + tx.receipt.gasUsed.toString().grey); + + let Tier0Token = await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier); + let Tier0Minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier); + assert.equal(Tier0Minted.toNumber(), Tier0Token.sub(delta_Token).toNumber()); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + 'Wallet POLY Balance not changed as expected' + ); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); }); - describe("Buy Tokens with POLY discount", async() => { - - it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async() => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await web3.eth.sendTransaction({ from: NONACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), "Raised USD not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional checks on getters - assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), investment_Token.toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), investment_Token.toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), investment_Token.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), 0, "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), investment_USD.toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), investment_ETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), 0, "investorInvestedPOLY not changed as expected"); - }); - - it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async() => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async() => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should successfully buy using fallback at tier 0 for ACCREDITED1", async() => { - let stoId = 2; - let tierId = 0; - - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await web3.eth.sendTransaction({ from: ACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async() => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async() => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - - // Additional checks on getters - let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_getTokensMinted = await I_USDTieredSTO_Array[stoId].getTokensMinted(); - let init_getTokensSoldForETH = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH); - let init_getTokensSoldForPOLY = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY); - let init_investorInvestedUSD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1); - let init_investorInvestedETH = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH); - let init_investorInvestedPOLY = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional checks on getters - assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), init_getTokensSold.add(investment_Token).toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), init_getTokensMinted.add(investment_Token).toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), init_getTokensSoldForETH.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), init_getTokensSoldForPOLY.add(investment_Token).toNumber(), "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), init_investorInvestedUSD.add(investment_USD).toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), init_investorInvestedETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), init_investorInvestedPOLY.add(investment_POLY).toNumber(), "investorInvestedPOLY not changed as expected"); - }); - - it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async() => { - let stoId = 2; - let tierId = 0; - - let investment_USD = _nonAccreditedLimitUSD[stoId]; - let investment_Token = await convert(stoId, tierId, true, "USD", "TOKEN", investment_USD); - let investment_ETH = await convert(stoId, tierId, true, "USD", "ETH", investment_USD); - let investment_POLY = await convert(stoId, tierId, true, "USD", "POLY", investment_USD); - - let refund_USD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); - let refund_Token = await convert(stoId, tierId, true, "USD", "TOKEN", refund_USD); - let refund_ETH = await convert(stoId, tierId, true, "USD", "ETH", refund_USD); - let refund_POLY = await convert(stoId, tierId, true, "USD", "POLY", refund_USD); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).add(refund_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).sub(refund_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).sub(refund_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should fail and revert when NONACCREDITED cap reached", async() => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1, gasPrice: GAS_PRICE}); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - }); - - it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { - let stoId = 2; - let tierId = 0; - - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); - - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); - - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); - - it("should successfully buy across tiers for POLY", async() => { - let stoId = 2; - let startTier = 0; - let endTier = 1; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); - - let delta_Token = BigNumber(5).mul(10**18); // Token - let polyTier0 = await convert(stoId, startTier, true, "TOKEN", "POLY", delta_Token); - let polyTier1 = await convert(stoId, endTier, true, "TOKEN", "POLY", delta_Token); - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH - - let tokensRemaining = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier)); - let prep_Token = tokensRemaining.sub(delta_Token); - let prep_POLY = await convert(stoId, startTier, true, "TOKEN", "POLY", prep_Token); - - await I_PolyToken.getTokens(prep_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, prep_POLY, {from: ACCREDITED1}); - let tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, prep_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - console.log(" Gas buyWithPOLY: ".grey+tx.receipt.gasUsed.toString().grey); - - let Tier0Token = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)); - let Tier0Minted = (await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier)); - assert.equal(Tier0Minted.toNumber(), Tier0Token.sub(delta_Token).toNumber()); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); - }); - - it("should successfully buy across the discount cap", async() => { - let stoId = 2; - let tierId = 1; - - let discount_Token = BigNumber(20).mul(10**18); - let discount_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", discount_Token); - - let regular_Token = BigNumber(10).mul(10**18); - let regular_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", regular_Token); - - let investment_Token = discount_Token.add(regular_Token); - let investment_POLY = discount_POLY.add(regular_POLY); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); - }); - - it("should buy out the rest of the sto", async() => { - let stoId = 2; - let tierId = 1; - - let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); - let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); - }); - - it("should fail and revert when all tiers sold out", async() => { - let stoId = 2; - let tierId = 1; - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); - let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); - let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - }); - - it("should fail and revert when all tiers sold out despite oracle price change", async() => { - let stoId = 2; - let tierId = 1; - - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY - - let investment_Token = BigNumber(5).mul(10**18); - let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); - - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); - await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: ACCREDITED1}); - - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); - - // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); + it('should successfully buy across the discount cap', async () => { + let stoId = 2; + let tierId = 1; + + let discount_Token = BigNumber(20).mul(10 ** 18); + let discount_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', discount_Token); + + let regular_Token = BigNumber(10).mul(10 ** 18); + let regular_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', regular_Token); + + let investment_Token = discount_Token.add(regular_Token); + let investment_POLY = discount_POLY.add(regular_POLY); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + 'Investor ETH Balance not changed as expected' + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + 'Investor POLY Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + 'Wallet POLY Balance not changed as expected' + ); }); - describe("Test getter functions", async() => { - - describe("Generic", async() => { - - it("should get the right number of investors", async() => { - assert.equal((await I_USDTieredSTO_Array[0].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[0].investorCount()).toNumber(), "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[1].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[1].investorCount()).toNumber(), "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[2].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[2].investorCount()).toNumber(), "Investor count not changed as expected"); - }); - - it("should get the right amounts invested", async() => { - assert.equal((await I_USDTieredSTO_Array[0].fundsRaised.call(ETH)).toNumber(), (await I_USDTieredSTO_Array[0].getRaised(0)).toNumber(), "getRaisedEther not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[0].fundsRaised.call(POLY)).toNumber(), (await I_USDTieredSTO_Array[0].getRaised(1)).toNumber(), "getRaisedPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[0].fundsRaisedUSD.call()).toNumber(), (await I_USDTieredSTO_Array[0].fundsRaisedUSD()).toNumber(), "fundsRaisedUSD not changed as expected"); - }); - }); - - describe("convertToUSD", async() => { - - it("should reset exchange rates", async() => { - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); - - it("should get the right conversion for ETH to USD", async() => { - // 20 ETH to 10000 USD - let ethInWei = BigNumber(web3.utils.toWei('20', 'ether')); - let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(ETH, ethInWei); - assert.equal(usdInWei.div(10**18).toNumber(), ethInWei.div(10**18).mul(USDETH.div(10**18)).toNumber()); - }); - - it("should get the right conversion for POLY to USD", async() => { - // 40000 POLY to 10000 USD - let polyInWei = BigNumber(web3.utils.toWei('40000', 'ether')); - let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(POLY, polyInWei); - assert.equal(usdInWei.div(10**18).toNumber(), polyInWei.div(10**18).mul(USDPOLY.div(10**18)).toNumber()); - }); - }); - - describe("convertFromUSD", async() => { - - it("should get the right conversion for USD to ETH", async() => { - // 10000 USD to 20 ETH - let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); - let ethInWei = await I_USDTieredSTO_Array[0].convertFromUSD(ETH, usdInWei); - assert.equal(ethInWei.div(10**18).toNumber(), usdInWei.div(10**18).div(USDETH.div(10**18)).toNumber()); - }); - - it("should get the right conversion for USD to POLY", async() => { - // 10000 USD to 40000 POLY - let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); - let polyInWei = await I_USDTieredSTO_Array[0].convertFromUSD(POLY, usdInWei); - assert.equal(polyInWei.div(10**18).toNumber(), usdInWei.div(10**18).div(USDPOLY.div(10**18)).toNumber()); - }); - }); + it('should buy out the rest of the sto', async () => { + let stoId = 2; + let tierId = 1; + + let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); + let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); + let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + 'Investor Token Balance not changed as expected' + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + 'STO Token Sold not changed as expected' + ); }); - describe("Test cases for the USDTieredSTOFactory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal((await I_USDTieredSTOFactory.setupCost.call()).toNumber(), STOSetupCost); - assert.equal(await I_USDTieredSTOFactory.getType.call(),3); - assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), - "USDTieredSTO", - "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.getDescription.call(), - "USD Tiered STO", - "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.getTitle.call(), - "USD Tiered STO", - "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), - "Initialises a USD tiered STO.", - "Wrong Module added"); - let tags = await I_USDTieredSTOFactory.getTags.call(); - assert.equal(web3.utils.hexToString(tags[0]),"USD"); - assert.equal(web3.utils.hexToString(tags[1]),"Tiered"); - assert.equal(web3.utils.hexToString(tags[2]),"POLY"); - assert.equal(web3.utils.hexToString(tags[3]),"ETH"); - - }); - }); + it('should fail and revert when all tiers sold out', async () => { + let stoId = 2; + let tierId = 1; + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); + let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); + let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, 'STO is not showing correct status'); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Buy with ETH ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + }); + + it('should fail and revert when all tiers sold out despite oracle price change', async () => { + let stoId = 2; + let tierId = 1; + + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY + + let investment_Token = BigNumber(5).mul(10 ** 18); + let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); + + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); + await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: ACCREDITED1 }); + + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Buy with ETH ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY NONACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Buy with ETH ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); + + // Buy with POLY ACCREDITED + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); + }); + + describe('Test getter functions', async () => { + describe('Generic', async () => { + it('should get the right number of investors', async () => { + assert.equal( + (await I_USDTieredSTO_Array[0].investorCount.call()).toNumber(), + (await I_USDTieredSTO_Array[0].investorCount()).toNumber(), + 'Investor count not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[1].investorCount.call()).toNumber(), + (await I_USDTieredSTO_Array[1].investorCount()).toNumber(), + 'Investor count not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[2].investorCount.call()).toNumber(), + (await I_USDTieredSTO_Array[2].investorCount()).toNumber(), + 'Investor count not changed as expected' + ); + }); + + it('should get the right amounts invested', async () => { + assert.equal( + (await I_USDTieredSTO_Array[0].fundsRaised.call(ETH)).toNumber(), + (await I_USDTieredSTO_Array[0].getRaised(0)).toNumber(), + 'getRaisedEther not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[0].fundsRaised.call(POLY)).toNumber(), + (await I_USDTieredSTO_Array[0].getRaised(1)).toNumber(), + 'getRaisedPOLY not changed as expected' + ); + assert.equal( + (await I_USDTieredSTO_Array[0].fundsRaisedUSD.call()).toNumber(), + (await I_USDTieredSTO_Array[0].fundsRaisedUSD()).toNumber(), + 'fundsRaisedUSD not changed as expected' + ); + }); + }); + + describe('convertToUSD', async () => { + it('should reset exchange rates', async () => { + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); + + it('should get the right conversion for ETH to USD', async () => { + // 20 ETH to 10000 USD + let ethInWei = BigNumber(web3.utils.toWei('20', 'ether')); + let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(ETH, ethInWei); + assert.equal( + usdInWei.div(10 ** 18).toNumber(), + ethInWei + .div(10 ** 18) + .mul(USDETH.div(10 ** 18)) + .toNumber() + ); + }); + + it('should get the right conversion for POLY to USD', async () => { + // 40000 POLY to 10000 USD + let polyInWei = BigNumber(web3.utils.toWei('40000', 'ether')); + let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(POLY, polyInWei); + assert.equal( + usdInWei.div(10 ** 18).toNumber(), + polyInWei + .div(10 ** 18) + .mul(USDPOLY.div(10 ** 18)) + .toNumber() + ); + }); + }); + + describe('convertFromUSD', async () => { + it('should get the right conversion for USD to ETH', async () => { + // 10000 USD to 20 ETH + let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); + let ethInWei = await I_USDTieredSTO_Array[0].convertFromUSD(ETH, usdInWei); + assert.equal( + ethInWei.div(10 ** 18).toNumber(), + usdInWei + .div(10 ** 18) + .div(USDETH.div(10 ** 18)) + .toNumber() + ); + }); + + it('should get the right conversion for USD to POLY', async () => { + // 10000 USD to 40000 POLY + let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); + let polyInWei = await I_USDTieredSTO_Array[0].convertFromUSD(POLY, usdInWei); + assert.equal( + polyInWei.div(10 ** 18).toNumber(), + usdInWei + .div(10 ** 18) + .div(USDPOLY.div(10 ** 18)) + .toNumber() + ); + }); + }); + }); + + describe('Test cases for the USDTieredSTOFactory', async () => { + it('should get the exact details of the factory', async () => { + assert.equal((await I_USDTieredSTOFactory.setupCost.call()).toNumber(), STOSetupCost); + assert.equal(await I_USDTieredSTOFactory.getType.call(), 3); + assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), 'USDTieredSTO', 'Wrong Module added'); + assert.equal(await I_USDTieredSTOFactory.getDescription.call(), 'USD Tiered STO', 'Wrong Module added'); + assert.equal(await I_USDTieredSTOFactory.getTitle.call(), 'USD Tiered STO', 'Wrong Module added'); + assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), 'Initialises a USD tiered STO.', 'Wrong Module added'); + let tags = await I_USDTieredSTOFactory.getTags.call(); + assert.equal(web3.utils.hexToString(tags[0]), 'USD'); + assert.equal(web3.utils.hexToString(tags[1]), 'Tiered'); + assert.equal(web3.utils.hexToString(tags[2]), 'POLY'); + assert.equal(web3.utils.hexToString(tags[3]), 'ETH'); + }); + }); }); diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index b41da159e..70d60284f 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); const USDTieredSTO = artifacts.require('./USDTieredSTO.sol'); const MockOracle = artifacts.require('./MockOracle.sol'); @@ -24,86 +24,86 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port const TOLERANCE = 2; // Allow balances to be off by 2 WEI for rounding purposes contract('USDTieredSTO Sim', accounts => { - // Accounts Variable declaration - let POLYMATH; - let ISSUER; - let WALLET; - let RESERVEWALLET; - let INVESTOR1; - let ACCREDITED1; - let ACCREDITED2; - let NONACCREDITED1; - let NONACCREDITED2; - let NOTWHITELISTED; - let NOTAPPROVED; - - let MESSAGE = "Transaction Should Fail!"; - const GAS_PRICE = 10000000000; // 10 GWEI - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_USDTieredSTOProxyFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_USDTieredSTOFactory; - let I_USDOracle; - let I_POLYOracle; - let I_STFactory; - let I_MRProxied; - let I_STRProxied; - let I_SecurityToken; - let I_USDTieredSTO_Array = []; - let I_PolyToken; - let I_DaiToken; - let I_PolymathRegistry; - - // SecurityToken Details for funds raise Type ETH - const NAME = "Team"; - const SYMBOL = "SAP"; - const TOKENDETAILS = "This is equity type of issuance"; - const DECIMALS = 18; - - // Module key - const TMKEY = 2; - const STOKEY = 3; - - // Initial fee for ticker registry and security token registry - const REGFEE = web3.utils.toWei("250"); - const STOSetupCost = 0; - - // MockOracle USD prices - const USDETH = BigNumber(500).mul(10**18); // 500 USD/ETH - const USDPOLY = BigNumber(25).mul(10**16); // 0.25 USD/POLY - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - // STO Configuration Arrays - let _startTime = []; - let _endTime = []; - let _ratePerTier = []; - let _ratePerTierDiscountPoly = []; - let _tokensPerTierTotal = []; - let _tokensPerTierDiscountPoly = []; - let _nonAccreditedLimitUSD = []; - let _minimumInvestmentUSD = []; - let _fundRaiseTypes = []; - let _wallet = []; - let _reserveWallet = []; - let _usdToken = []; - - /* function configure( + // Accounts Variable declaration + let POLYMATH; + let ISSUER; + let WALLET; + let RESERVEWALLET; + let INVESTOR1; + let ACCREDITED1; + let ACCREDITED2; + let NONACCREDITED1; + let NONACCREDITED2; + let NOTWHITELISTED; + let NOTAPPROVED; + + let MESSAGE = 'Transaction Should Fail!'; + const GAS_PRICE = 10000000000; // 10 GWEI + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_USDTieredSTOProxyFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_USDTieredSTOFactory; + let I_USDOracle; + let I_POLYOracle; + let I_STFactory; + let I_MRProxied; + let I_STRProxied; + let I_SecurityToken; + let I_USDTieredSTO_Array = []; + let I_PolyToken; + let I_DaiToken; + let I_PolymathRegistry; + + // SecurityToken Details for funds raise Type ETH + const NAME = 'Team'; + const SYMBOL = 'SAP'; + const TOKENDETAILS = 'This is equity type of issuance'; + const DECIMALS = 18; + + // Module key + const TMKEY = 2; + const STOKEY = 3; + + // Initial fee for ticker registry and security token registry + const REGFEE = web3.utils.toWei('250'); + const STOSetupCost = 0; + + // MockOracle USD prices + const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH + const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + // STO Configuration Arrays + let _startTime = []; + let _endTime = []; + let _ratePerTier = []; + let _ratePerTierDiscountPoly = []; + let _tokensPerTierTotal = []; + let _tokensPerTierDiscountPoly = []; + let _nonAccreditedLimitUSD = []; + let _minimumInvestmentUSD = []; + let _fundRaiseTypes = []; + let _wallet = []; + let _reserveWallet = []; + let _usdToken = []; + + /* function configure( uint256 _startTime, uint256 _endTime, uint256[] _ratePerTier, @@ -117,184 +117,197 @@ contract('USDTieredSTO Sim', accounts => { address _reserveWallet, address _usdToken ) */ - const functionSignature = { - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_startTime' - },{ - type: 'uint256', - name: '_endTime' - },{ - type: 'uint256[]', - name: '_ratePerTier' - },{ - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - },{ - type: 'uint256[]', - name: '_tokensPerTier' - },{ - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - },{ - type: 'uint256', - name: '_nonAccreditedLimitUSD' - },{ - type: 'uint256', - name: '_minimumInvestmentUSD' - },{ - type: 'uint8[]', - name: '_fundRaiseTypes' - },{ - type: 'address', - name: '_wallet' - },{ - type: 'address', - name: '_reserveWallet' - },{ - type: 'address', - name: '_usdToken' - }] - }; - - function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - } - - before(async() => { - // Accounts setup - POLYMATH = accounts[0]; - ISSUER = accounts[1]; - WALLET = accounts[2]; - RESERVEWALLET = WALLET; - ACCREDITED1 = accounts[3]; - ACCREDITED2 = accounts[4]; - NONACCREDITED1 = accounts[5]; - NONACCREDITED2 = accounts[6]; - NOTWHITELISTED = accounts[7]; - NOTAPPROVED = accounts[8]; - INVESTOR1 = accounts[9]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), ISSUER); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: POLYMATH - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - - // STEP 3: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the proxy - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - - // STEP 6: Deploy the USDTieredSTOFactory - - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: ISSUER }); - - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "USDTieredSTOFactory contract was not deployed" - ); - - - - // Step 8: Deploy the STFactory contract + const functionSignature = { + name: 'configure', + type: 'function', + inputs: [ + { + type: 'uint256', + name: '_startTime' + }, + { + type: 'uint256', + name: '_endTime' + }, + { + type: 'uint256[]', + name: '_ratePerTier' + }, + { + type: 'uint256[]', + name: '_ratePerTierDiscountPoly' + }, + { + type: 'uint256[]', + name: '_tokensPerTier' + }, + { + type: 'uint256[]', + name: '_tokensPerTierDiscountPoly' + }, + { + type: 'uint256', + name: '_nonAccreditedLimitUSD' + }, + { + type: 'uint256', + name: '_minimumInvestmentUSD' + }, + { + type: 'uint8[]', + name: '_fundRaiseTypes' + }, + { + type: 'address', + name: '_wallet' + }, + { + type: 'address', + name: '_reserveWallet' + }, + { + type: 'address', + name: '_usdToken' + } + ] + }; + + function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + before(async () => { + // Accounts setup + POLYMATH = accounts[0]; + ISSUER = accounts[1]; + WALLET = accounts[2]; + RESERVEWALLET = WALLET; + ACCREDITED1 = accounts[3]; + ACCREDITED2 = accounts[4]; + NONACCREDITED1 = accounts[5]; + NONACCREDITED2 = accounts[6]; + NOTWHITELISTED = accounts[7]; + NOTAPPROVED = accounts[8]; + INVESTOR1 = accounts[9]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + I_DaiToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: POLYMATH + }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); + // STEP 3: Deploy the ModuleRegistry - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // Step 9: Deploy the SecurityTokenRegistry + // STEP 3: Deploy the GeneralTransferManagerFactory - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // STEP 4: Deploy the GeneralDelegateManagerFactory - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: POLYMATH}); - await I_MRProxied.updateFromRegistry({from: POLYMATH}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - // STEP 7: Register the Modules with the ModuleRegistry contract + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + // STEP 5: Deploy the proxy + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); + // STEP 6: Deploy the USDTieredSTOFactory - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); - - // 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 }); - await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { + from: ISSUER + }); - // Printing all the contract addresses - console.log(` + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'USDTieredSTOFactory contract was not deployed' + ); + + // Step 8: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + + // Step 9: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 10: update the registries addresses from the PolymathRegistry contract + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + REGFEE, + REGFEE, + I_PolyToken.address, + POLYMATH + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); + await I_MRProxied.updateFromRegistry({ from: POLYMATH }); + + // STEP 7: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + + // 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 }); + await I_PolymathRegistry.changeAddress('PolyUsdOracle', I_POLYOracle.address, { from: POLYMATH }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -313,125 +326,147 @@ contract('USDTieredSTO Sim', accounts => { USDTieredSTOProxyFactory: ${I_USDTieredSTOProxyFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Deploy the STO', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from: ISSUER }); + assert.equal(tx.logs[0].args._owner, ISSUER); + assert.equal(tx.logs[0].args._ticker, SYMBOL); }); - describe("Deploy the STO", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from : ISSUER }); - assert.equal(tx.logs[0].args._owner, ISSUER); - assert.equal(tx.logs[0].args._ticker, SYMBOL); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); - assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), TMKEY); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(TMKEY, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - it("Should successfully attach the first STO module to the security token", async () => { - let stoId = 0; - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([ - BigNumber(0.05*10**18), BigNumber(0.13*10**18), BigNumber(0.17*10**18) - ]); // [ 0.05 USD/Token, 0.10 USD/Token, 0.15 USD/Token ] - _ratePerTierDiscountPoly.push([ - BigNumber(0.05*10**18), BigNumber(0.08*10**18), BigNumber(0.13*10**18) - ]); // [ 0.05 USD/Token, 0.08 USD/Token, 0.13 USD/Token ] - _tokensPerTierTotal.push([ - BigNumber(200*10**18), BigNumber(500*10**18), BigNumber(300*10**18) - ]); // [ 1000 Token, 2000 Token, 1500 Token ] - _tokensPerTierDiscountPoly.push([ - BigNumber(0), BigNumber(50*10**18), BigNumber(300*10**18) - ]); // [ 0 Token, 1000 Token, 1500 Token ] - _nonAccreditedLimitUSD.push(BigNumber(10*10**18)); // 20 USD - _minimumInvestmentUSD.push(BigNumber(0)); // 1 wei USD - _fundRaiseTypes.push([0,1,2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - - assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); - } - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].getNumberOfTiers()), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); - assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); - }); - - it("Should successfully prepare the STO", async() => { - let stoId = 0; - - // Start STO - await increaseTime(duration.days(3)); - - // Whitelist - let fromTime = latestTime() + duration.days(15); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let canBuyFromSTO = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NOTAPPROVED, fromTime, toTime, expiryTime, false, { from: ISSUER }); - - await increaseTime(duration.days(3)); - - // Accreditation - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1, ACCREDITED2], [true, true], { from: ISSUER }); - await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, NONACCREDITED2], [false, false], { from: ISSUER }); - }); + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); + assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), TMKEY); + assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); }); - describe("Simulate purchasing", async() => { + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(TMKEY, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it('Should successfully attach the first STO module to the security token', async () => { + let stoId = 0; + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([BigNumber(0.05 * 10 ** 18), BigNumber(0.13 * 10 ** 18), BigNumber(0.17 * 10 ** 18)]); // [ 0.05 USD/Token, 0.10 USD/Token, 0.15 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(0.05 * 10 ** 18), BigNumber(0.08 * 10 ** 18), BigNumber(0.13 * 10 ** 18)]); // [ 0.05 USD/Token, 0.08 USD/Token, 0.13 USD/Token ] + _tokensPerTierTotal.push([BigNumber(200 * 10 ** 18), BigNumber(500 * 10 ** 18), BigNumber(300 * 10 ** 18)]); // [ 1000 Token, 2000 Token, 1500 Token ] + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(50 * 10 ** 18), BigNumber(300 * 10 ** 18)]); // [ 0 Token, 1000 Token, 1500 Token ] + _nonAccreditedLimitUSD.push(BigNumber(10 * 10 ** 18)); // 20 USD + _minimumInvestmentUSD.push(BigNumber(0)); // 1 wei USD + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], 'Incorrect _startTime in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], 'Incorrect _endTime in config'); + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), + _ratePerTier[stoId][i].toNumber(), + 'Incorrect _ratePerTier in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), + _ratePerTierDiscountPoly[stoId][i].toNumber(), + 'Incorrect _ratePerTierDiscountPoly in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), + _tokensPerTierTotal[stoId][i].toNumber(), + 'Incorrect _tokensPerTierTotal in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), + _tokensPerTierDiscountPoly[stoId][i].toNumber(), + 'Incorrect _tokensPerTierDiscountPoly in config' + ); + } + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + _nonAccreditedLimitUSD[stoId].toNumber(), + 'Incorrect _nonAccreditedLimitUSD in config' + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + _minimumInvestmentUSD[stoId].toNumber(), + 'Incorrect _minimumInvestmentUSD in config' + ); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], 'Incorrect _wallet in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(), _reserveWallet[stoId], 'Incorrect _reserveWallet in config'); + assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, 'Incorrect number of tiers'); + assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, 'Incorrect number of permissions'); + }); - it("Should successfully complete simulation", async() => { - let stoId = 0; + it('Should successfully prepare the STO', async () => { + let stoId = 0; - console.log(` + // Start STO + await increaseTime(duration.days(3)); + + // Whitelist + let fromTime = latestTime() + duration.days(15); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let canBuyFromSTO = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NOTAPPROVED, fromTime, toTime, expiryTime, false, { from: ISSUER }); + + await increaseTime(duration.days(3)); + + // Accreditation + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1, ACCREDITED2], [true, true], { from: ISSUER }); + await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, NONACCREDITED2], [false, false], { from: ISSUER }); + }); + }); + + describe('Simulate purchasing', async () => { + it('Should successfully complete simulation', async () => { + let stoId = 0; + + console.log(` ------------------- Investor Addresses ------------------- ACCREDITED1: ${ACCREDITED1} ACCREDITED2: ${ACCREDITED2} @@ -442,320 +477,505 @@ contract('USDTieredSTO Sim', accounts => { ---------------------------------------------------------- `); - let totalTokens = BigNumber(0); - for (var i = 0; i < _tokensPerTierTotal[stoId].length; i++) { - totalTokens = totalTokens.add(_tokensPerTierTotal[stoId][i]); - } - console.log('totalTokens: '+totalTokens.div(10**18).toNumber()); - let tokensSold = BigNumber(0); - while (true) { - switch (getRandomInt(0,5)) { - case 0: // ACCREDITED1 - await invest(ACCREDITED1, true); - break; - case 1: // ACCREDITED2 - await invest(ACCREDITED2, true); - break; - case 2: // NONACCREDITED1 - let usd_NONACCREDITED1 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); - if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED1)) // under non-accredited cap - await invest(NONACCREDITED1, false); - else // over non-accredited cap - await investFAIL(NONACCREDITED1); - break; - case 3: // NONACCREDITED2 - let usd_NONACCREDITED2 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED2); - if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED2)) // under non-accredited cap - await invest(NONACCREDITED2, false); - else // over non-accredited cap - await investFAIL(NONACCREDITED2); - break; - case 4: // NOTWHITELISTED - await investFAIL(NOTWHITELISTED); - break; - case 5: // NOTAPPROVED - await investFAIL(NOTAPPROVED); - break; - } - console.log("Next round"); - tokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - console.log("Tokens Sold: " + tokensSold.toString()); - if (tokensSold.gte(totalTokens.sub(1*10**18))) { - console.log(`${tokensSold} tokens sold, simulation completed successfully!`.green); - break; - } - } - - async function invest(_investor, _isAccredited) { // need to add check if reached non-accredited cap - let USD_remaining; - if (!_isAccredited) { - let USD_to_date = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(_investor); - USD_remaining = _nonAccreditedLimitUSD[stoId].sub(USD_to_date); - } else { - USD_remaining = totalTokens.mul(2); - } - - let log_remaining = USD_remaining; - let isPoly = Math.random() >= 0.33; - let isDai = Math.random() >= 0.33; - - let Token_counter = BigNumber(getRandomInt(1*10**10,50*10**10)).mul(10**8); - let investment_USD = BigNumber(0); - let investment_ETH = BigNumber(0); - let investment_POLY = BigNumber(0); - let investment_DAI = BigNumber(0); - let investment_Token = BigNumber(0); - - let Tokens_total = []; - let Tokens_discount = []; - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - Tokens_total.push((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(i))); - Tokens_discount.push((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierDiscountPoly.call(i))); + let totalTokens = BigNumber(0); + for (var i = 0; i < _tokensPerTierTotal[stoId].length; i++) { + totalTokens = totalTokens.add(_tokensPerTierTotal[stoId][i]); + } + console.log('totalTokens: ' + totalTokens.div(10 ** 18).toNumber()); + let tokensSold = BigNumber(0); + while (true) { + switch (getRandomInt(0, 5)) { + case 0: // ACCREDITED1 + await invest(ACCREDITED1, true); + break; + case 1: // ACCREDITED2 + await invest(ACCREDITED2, true); + break; + case 2: // NONACCREDITED1 + let usd_NONACCREDITED1 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); + if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED1)) + // under non-accredited cap + await invest(NONACCREDITED1, false); + // over non-accredited cap + else await investFAIL(NONACCREDITED1); + break; + case 3: // NONACCREDITED2 + let usd_NONACCREDITED2 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED2); + if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED2)) + // under non-accredited cap + await invest(NONACCREDITED2, false); + // over non-accredited cap + else await investFAIL(NONACCREDITED2); + break; + case 4: // NOTWHITELISTED + await investFAIL(NOTWHITELISTED); + break; + case 5: // NOTAPPROVED + await investFAIL(NOTAPPROVED); + break; + } + console.log('Next round'); + tokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + console.log('Tokens Sold: ' + tokensSold.toString()); + if (tokensSold.gte(totalTokens.sub(1 * 10 ** 18))) { + console.log(`${tokensSold} tokens sold, simulation completed successfully!`.green); + break; + } + } + + async function invest(_investor, _isAccredited) { + // need to add check if reached non-accredited cap + let USD_remaining; + if (!_isAccredited) { + let USD_to_date = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(_investor); + USD_remaining = _nonAccreditedLimitUSD[stoId].sub(USD_to_date); + } else { + USD_remaining = totalTokens.mul(2); + } + + let log_remaining = USD_remaining; + let isPoly = Math.random() >= 0.33; + let isDai = Math.random() >= 0.33; + + let Token_counter = BigNumber(getRandomInt(1 * 10 ** 10, 50 * 10 ** 10)).mul(10 ** 8); + let investment_USD = BigNumber(0); + let investment_ETH = BigNumber(0); + let investment_POLY = BigNumber(0); + let investment_DAI = BigNumber(0); + let investment_Token = BigNumber(0); + + let Tokens_total = []; + let Tokens_discount = []; + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + Tokens_total.push( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(i)) + ); + Tokens_discount.push( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).sub( + await I_USDTieredSTO_Array[stoId].mintedPerTierDiscountPoly.call(i) + ) + ); + } + + let tier = 0; + let Token_Tier; + let USD_Tier; + let POLY_Tier; + let ETH_Tier; + let DAI_Tier; + + let USD_overflow; + let Token_overflow; + + while (Token_counter.gt(0)) { + if (tier == _ratePerTier[stoId].length) { + break; + } + if (Tokens_total[tier].gt(0)) { + if (isPoly) { + // 1. POLY and discount (consume up to cap then move to regular) + if (Tokens_discount[tier].gt(0)) { + Token_Tier = BigNumber.min([Tokens_total[tier], Tokens_discount[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTierDiscountPoly[stoId][tier].div(10 ** 18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTierDiscountPoly[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); } - - let tier = 0; - let Token_Tier; - let USD_Tier; - let POLY_Tier; - let ETH_Tier; - let DAI_Tier; - - - let USD_overflow; - let Token_overflow; - - while (Token_counter.gt(0)) { - if (tier == _ratePerTier[stoId].length) { - break; - } - if (Tokens_total[tier].gt(0)) { - if (isPoly) { - // 1. POLY and discount (consume up to cap then move to regular) - if (Tokens_discount[tier].gt(0)) { - Token_Tier = BigNumber.min([Tokens_total[tier], Tokens_discount[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTierDiscountPoly[stoId][tier].div(10**18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTierDiscountPoly[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); - } - POLY_Tier = USD_Tier.mul(10**18).round(0).div(USDPOLY).round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Tokens_discount[tier] = Tokens_discount[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_POLY = investment_POLY.add(POLY_Tier); - } - // 2. POLY and regular (consume up to cap then skip to next tier) - if (Tokens_total[tier].gt(0) && Token_counter.gt(0)) { - Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); - } - POLY_Tier = USD_Tier.mul(10**18).round(0).div(USDPOLY).round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_POLY = investment_POLY.add(POLY_Tier); - } - } else if (isDai) { - // 3. DAI (consume up to cap then skip to next tier) - Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); - } - DAI_Tier = USD_Tier.round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_DAI = investment_USD; - } else { - // 4. ETH (consume up to cap then skip to next tier) - Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); - } - ETH_Tier = USD_Tier.mul(10**18).round(0).div(USDETH).round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_ETH = investment_ETH.add(ETH_Tier); - } - } - tier++ + POLY_Tier = USD_Tier.mul(10 ** 18) + .round(0) + .div(USDPOLY) + .round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Tokens_discount[tier] = Tokens_discount[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_POLY = investment_POLY.add(POLY_Tier); + } + // 2. POLY and regular (consume up to cap then skip to next tier) + if (Tokens_total[tier].gt(0) && Token_counter.gt(0)) { + Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); } - - await processInvestment(_investor, investment_Token, investment_USD, investment_POLY, investment_DAI, investment_ETH, isPoly, isDai, log_remaining, Tokens_total, Tokens_discount, tokensSold); + POLY_Tier = USD_Tier.mul(10 ** 18) + .round(0) + .div(USDPOLY) + .round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_POLY = investment_POLY.add(POLY_Tier); + } + } else if (isDai) { + // 3. DAI (consume up to cap then skip to next tier) + Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); + } + DAI_Tier = USD_Tier.round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_DAI = investment_USD; + } else { + // 4. ETH (consume up to cap then skip to next tier) + Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); + } + ETH_Tier = USD_Tier.mul(10 ** 18) + .round(0) + .div(USDETH) + .round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_ETH = investment_ETH.add(ETH_Tier); } - - async function investFAIL(_investor) { - let isPoly = Math.random() >= 0.3; - let isDAI = Math.random() >= 0.3; - let investment_POLY = BigNumber(40*10**18); // 10 USD = 40 POLY - let investment_ETH = BigNumber(0.02*10**18); // 10 USD = 0.02 ETH - let investment_DAI = BigNumber(10*10**18); // 10 USD = DAI DAI - - - await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); - } - - async function processInvestment(_investor, investment_Token, investment_USD, investment_POLY, investment_DAI, investment_ETH, isPoly, isDai, log_remaining, Tokens_total, Tokens_discount, tokensSold) { - investment_Token = investment_Token.round(0); - investment_USD = investment_USD.round(0); - investment_POLY = investment_POLY.round(0); - investment_DAI = investment_DAI.round(0); - investment_ETH = investment_ETH.round(0); - console.log(` + } + tier++; + } + + await processInvestment( + _investor, + investment_Token, + investment_USD, + investment_POLY, + investment_DAI, + investment_ETH, + isPoly, + isDai, + log_remaining, + Tokens_total, + Tokens_discount, + tokensSold + ); + } + + async function investFAIL(_investor) { + let isPoly = Math.random() >= 0.3; + let isDAI = Math.random() >= 0.3; + let investment_POLY = BigNumber(40 * 10 ** 18); // 10 USD = 40 POLY + let investment_ETH = BigNumber(0.02 * 10 ** 18); // 10 USD = 0.02 ETH + let investment_DAI = BigNumber(10 * 10 ** 18); // 10 USD = DAI DAI + + await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); + } + + async function processInvestment( + _investor, + investment_Token, + investment_USD, + investment_POLY, + investment_DAI, + investment_ETH, + isPoly, + isDai, + log_remaining, + Tokens_total, + Tokens_discount, + tokensSold + ) { + investment_Token = investment_Token.round(0); + investment_USD = investment_USD.round(0); + investment_POLY = investment_POLY.round(0); + investment_DAI = investment_DAI.round(0); + investment_ETH = investment_ETH.round(0); + console.log(` ------------------- New Investment ------------------- Investor: ${_investor} - N-A USD Remaining: ${log_remaining.div(10**18)} + N-A USD Remaining: ${log_remaining.div(10 ** 18)} Total Cap Remaining: ${Tokens_total} Discount Cap Remaining: ${Tokens_discount} - Total Tokens Sold: ${tokensSold.div(10**18)} - Token Investment: ${investment_Token.div(10**18)} - USD Investment: ${investment_USD.div(10**18)} - POLY Investment: ${investment_POLY.div(10**18)} - DAI Investment: ${investment_DAI.div(10**18)} - ETH Investment: ${investment_ETH.div(10**18)} + Total Tokens Sold: ${tokensSold.div(10 ** 18)} + Token Investment: ${investment_Token.div(10 ** 18)} + USD Investment: ${investment_USD.div(10 ** 18)} + POLY Investment: ${investment_POLY.div(10 ** 18)} + DAI Investment: ${investment_DAI.div(10 ** 18)} + ETH Investment: ${investment_ETH.div(10 ** 18)} ------------------------------------------------------ `); - if (isPoly) { - await I_PolyToken.getTokens(investment_POLY, _investor); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: _investor}); - } else if (isDai) { - await I_DaiToken.getTokens(investment_DAI, _investor); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: _investor}); - } - - // console.log(await I_USDTieredSTO_Array[stoId].isOpen()); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); - let init_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - let tx; - let gasCost = BigNumber(0); - - if (isPoly && investment_POLY.gt(10)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE }); - gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log(`buyWithPOLY: ${investment_Token.div(10**18)} tokens for ${investment_POLY.div(10**18)} POLY by ${_investor}`.yellow); - } else if (isDai && investment_DAI.gt(10)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE }); - gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log(`buyWithUSD: ${investment_Token.div(10**18)} tokens for ${investment_DAI.div(10**18)} DAI by ${_investor}`.yellow); - } else if (investment_ETH.gt(0)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE }); - gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log(`buyWithETH: ${investment_Token.div(10**18)} tokens for ${investment_ETH.div(10**18)} ETH by ${_investor}`.yellow); - } - console.log(investment_POLY.toNumber()); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); - let final_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - // console.log('init_TokenSupply: '+init_TokenSupply.div(10**18).toNumber()); - // console.log('final_TokenSupply: '+final_TokenSupply.div(10**18).toNumber()); - - if (isPoly) { - assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); - assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); - assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); - assert.closeTo(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), TOLERANCE, "Investor POLY Balance not changed as expected"); - assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); - assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, "STO POLY Balance not changed as expected"); - assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); - assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, "Raised ETH not changed as expected"); - assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), TOLERANCE, "Raised POLY not changed as expected"); - assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); - assert.closeTo(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), TOLERANCE, "Wallet POLY Balance not changed as expected"); - } else if (isDai) { - assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); - assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); - assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); - assert.closeTo(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), TOLERANCE, "Investor DAI Balance not changed as expected"); - assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); - assert.closeTo(final_STODAIBal.toNumber(), init_STODAIBal.toNumber(), TOLERANCE, "STO DAI Balance not changed as expected"); - assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); - assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, "Raised ETH not changed as expected"); - assert.closeTo(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), TOLERANCE, "Raised DAI not changed as expected"); - assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); - assert.closeTo(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), TOLERANCE, "Wallet DAI Balance not changed as expected"); - } else { - assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); - assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); - assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).sub(investment_ETH).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); - assert.closeTo(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), TOLERANCE, "Investor POLY Balance not changed as expected"); - assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); - assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, "STO POLY Balance not changed as expected"); - assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); - assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), TOLERANCE, "Raised ETH not changed as expected"); - assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), TOLERANCE, "Raised POLY not changed as expected"); - assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); - assert.closeTo(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), TOLERANCE, "Wallet POLY Balance not changed as expected"); - } - } - }); + if (isPoly) { + await I_PolyToken.getTokens(investment_POLY, _investor); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: _investor }); + } else if (isDai) { + await I_DaiToken.getTokens(investment_DAI, _investor); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: _investor }); + } + + // console.log(await I_USDTieredSTO_Array[stoId].isOpen()); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); + let init_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + let tx; + let gasCost = BigNumber(0); + + if (isPoly && investment_POLY.gt(10)) { + tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE }); + gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); + console.log( + `buyWithPOLY: ${investment_Token.div(10 ** 18)} tokens for ${investment_POLY.div(10 ** 18)} POLY by ${_investor}`.yellow + ); + } else if (isDai && investment_DAI.gt(10)) { + tx = await I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE }); + gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); + console.log( + `buyWithUSD: ${investment_Token.div(10 ** 18)} tokens for ${investment_DAI.div(10 ** 18)} DAI by ${_investor}`.yellow + ); + } else if (investment_ETH.gt(0)) { + tx = await I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE }); + gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); + console.log( + `buyWithETH: ${investment_Token.div(10 ** 18)} tokens for ${investment_ETH.div(10 ** 18)} ETH by ${_investor}`.yellow + ); + } + console.log(investment_POLY.toNumber()); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); + let final_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + // console.log('init_TokenSupply: '+init_TokenSupply.div(10**18).toNumber()); + // console.log('final_TokenSupply: '+final_TokenSupply.div(10**18).toNumber()); + + if (isPoly) { + assert.closeTo( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + TOLERANCE, + 'Token Supply not changed as expected' + ); + assert.closeTo( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + TOLERANCE, + 'Investor Token Balance not changed as expected' + ); + assert.closeTo( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost).toNumber(), + TOLERANCE, + 'Investor ETH Balance not changed as expected' + ); + assert.closeTo( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + TOLERANCE, + 'Investor POLY Balance not changed as expected' + ); + assert.closeTo( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + TOLERANCE, + 'STO Token Sold not changed as expected' + ); + assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, 'STO ETH Balance not changed as expected'); + assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, 'STO POLY Balance not changed as expected'); + assert.closeTo( + final_RaisedUSD.toNumber(), + init_RaisedUSD.add(investment_USD).toNumber(), + TOLERANCE, + 'Raised USD not changed as expected' + ); + assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, 'Raised ETH not changed as expected'); + assert.closeTo( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + TOLERANCE, + 'Raised POLY not changed as expected' + ); + assert.closeTo( + final_WalletETHBal.toNumber(), + init_WalletETHBal.toNumber(), + TOLERANCE, + 'Wallet ETH Balance not changed as expected' + ); + assert.closeTo( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + TOLERANCE, + 'Wallet POLY Balance not changed as expected' + ); + } else if (isDai) { + assert.closeTo( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + TOLERANCE, + 'Token Supply not changed as expected' + ); + assert.closeTo( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + TOLERANCE, + 'Investor Token Balance not changed as expected' + ); + assert.closeTo( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost).toNumber(), + TOLERANCE, + 'Investor ETH Balance not changed as expected' + ); + assert.closeTo( + final_InvestorDAIBal.toNumber(), + init_InvestorDAIBal.sub(investment_DAI).toNumber(), + TOLERANCE, + 'Investor DAI Balance not changed as expected' + ); + assert.closeTo( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + TOLERANCE, + 'STO Token Sold not changed as expected' + ); + assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, 'STO ETH Balance not changed as expected'); + assert.closeTo(final_STODAIBal.toNumber(), init_STODAIBal.toNumber(), TOLERANCE, 'STO DAI Balance not changed as expected'); + assert.closeTo( + final_RaisedUSD.toNumber(), + init_RaisedUSD.add(investment_USD).toNumber(), + TOLERANCE, + 'Raised USD not changed as expected' + ); + assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, 'Raised ETH not changed as expected'); + assert.closeTo( + final_RaisedDAI.toNumber(), + init_RaisedDAI.add(investment_DAI).toNumber(), + TOLERANCE, + 'Raised DAI not changed as expected' + ); + assert.closeTo( + final_WalletETHBal.toNumber(), + init_WalletETHBal.toNumber(), + TOLERANCE, + 'Wallet ETH Balance not changed as expected' + ); + assert.closeTo( + final_WalletDAIBal.toNumber(), + init_WalletDAIBal.add(investment_DAI).toNumber(), + TOLERANCE, + 'Wallet DAI Balance not changed as expected' + ); + } else { + assert.closeTo( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + TOLERANCE, + 'Token Supply not changed as expected' + ); + assert.closeTo( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + TOLERANCE, + 'Investor Token Balance not changed as expected' + ); + assert.closeTo( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost) + .sub(investment_ETH) + .toNumber(), + TOLERANCE, + 'Investor ETH Balance not changed as expected' + ); + assert.closeTo( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + TOLERANCE, + 'Investor POLY Balance not changed as expected' + ); + assert.closeTo( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + TOLERANCE, + 'STO Token Sold not changed as expected' + ); + assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, 'STO ETH Balance not changed as expected'); + assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, 'STO POLY Balance not changed as expected'); + assert.closeTo( + final_RaisedUSD.toNumber(), + init_RaisedUSD.add(investment_USD).toNumber(), + TOLERANCE, + 'Raised USD not changed as expected' + ); + assert.closeTo( + final_RaisedETH.toNumber(), + init_RaisedETH.add(investment_ETH).toNumber(), + TOLERANCE, + 'Raised ETH not changed as expected' + ); + assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), TOLERANCE, 'Raised POLY not changed as expected'); + assert.closeTo( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + TOLERANCE, + 'Wallet ETH Balance not changed as expected' + ); + assert.closeTo( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.toNumber(), + TOLERANCE, + 'Wallet POLY Balance not changed as expected' + ); + } + } }); + }); }); function near(x, y, message) { - assert.isAtMost(x, y) - + assert.isAtMost(x, y); } diff --git a/test/r_concurrent_STO.js b/test/r_concurrent_STO.js index f01a36436..78e7cc17b 100644 --- a/test/r_concurrent_STO.js +++ b/test/r_concurrent_STO.js @@ -10,7 +10,7 @@ const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const PreSaleSTOFactory = artifacts.require('./PreSaleSTOFactory.sol'); const PreSaleSTO = artifacts.require('./PreSaleSTO.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -26,182 +26,182 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('Concurrent STO', accounts => { - // Accounts variable declaration - let account_polymath; - let account_issuer; - let account_fundsReceiver; - let account_investor1; - let account_investor2; - let account_investor3; - - // Contract instance declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManagerFactory; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_STFactory; - let I_MRProxied; - let I_STRProxied; - let I_SecurityTokenRegistry; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // STO instance declaration - let I_CappedSTOFactory; - let I_DummySTOFactory; - let I_PreSaleSTOFactory; - let I_STO_Array = []; - - // Error message - let message = "Transaction Should Fail!"; - - // Initial fees - const initRegFee = web3.utils.toWei("250"); - const STOSetupCost = 200 * Math.pow(10, 18); - - // Module keys - const transferManagerKey = 2; - const stoKey = 3; - - // Configure function signature for STO deployment - - const CappedSTOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const DummySTOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const PresaleSTOParameters = ['uint256']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_fundsReceiver = accounts[2]; - account_investor1 = accounts[3]; - account_investor2 = accounts[4]; - account_investor3 = accounts[5] - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_issuer); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry + // Accounts variable declaration + let account_polymath; + let account_issuer; + let account_fundsReceiver; + let account_investor1; + let account_investor2; + let account_investor3; + + // Contract instance declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManagerFactory; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_STFactory; + let I_MRProxied; + let I_STRProxied; + let I_SecurityTokenRegistry; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // STO instance declaration + let I_CappedSTOFactory; + let I_DummySTOFactory; + let I_PreSaleSTOFactory; + let I_STO_Array = []; + + // Error message + let message = 'Transaction Should Fail!'; + + // Initial fees + const initRegFee = web3.utils.toWei('250'); + const STOSetupCost = 200 * Math.pow(10, 18); + + // Module keys + const transferManagerKey = 2; + const stoKey = 3; + + // Configure function signature for STO deployment + + const CappedSTOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + const DummySTOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const PresaleSTOParameters = ['uint256']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_fundsReceiver = accounts[2]; + account_investor1 = accounts[3]; + account_investor2 = accounts[4]; + account_investor3 = accounts[5]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_issuer); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + // STEP 3: Deploy the ModuleRegistry - // STEP 2: Deploy the GeneralTransferManagerFactory + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + // STEP 2: Deploy the GeneralTransferManagerFactory - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - // STEP 3: Deploy the GeneralPermissionManagerFactory + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + // STEP 3: Deploy the GeneralPermissionManagerFactory - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - // STEP 4: Deploy the STO Factories + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); + // STEP 4: Deploy the STO Factories - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); + I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CappedSTOFactory contract was not deployed' + ); - // Step 8: Deploy the STFactory contract + // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - // Step 9: Deploy the SecurityTokenRegistry contract + // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // STEP 5: Register the Modules with the ModuleRegistry contract + // STEP 5: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STO Factories - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + // (C) : Register the STO Factories + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); + await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -218,148 +218,141 @@ contract('Concurrent STO', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate Security Token', async () => { + // SecurityToken Details for funds raise Type ETH + const name = 'Team'; + const symbol = 'SAP'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.getTokens(initRegFee, account_issuer); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); + let tx = await I_STRProxied.registerTicker(account_issuer, symbol, name, { from: account_issuer }); + assert.equal(tx.logs[0].args._owner, account_issuer); + assert.equal(tx.logs[0].args._ticker, symbol); + }); + + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.getTokens(initRegFee, account_issuer); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_issuer }); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); }); - describe("Generate Security Token", async() => { - // SecurityToken Details for funds raise Type ETH - const name = "Team"; - const symbol = "SAP"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.getTokens(initRegFee, account_issuer); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); - let tx = await I_STRProxied.registerTicker(account_issuer, symbol, name, { from : account_issuer }); - assert.equal(tx.logs[0].args._owner, account_issuer); - assert.equal(tx.logs[0].args._ticker, symbol); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.getTokens(initRegFee, account_issuer); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer}); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_issuer }); - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - it("Should whitelist account_investor1", async() => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let canBuyFromSTO = true; - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - canBuyFromSTO, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); - }); + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - describe("Add STO and verify transfer", async() => { - - it("Should attach STO modules up to the max number, then fail", async() => { - const MAX_MODULES = 10; - const startTime = latestTime() + duration.days(1); - const endTime = latestTime() + duration.days(90); - const cap = web3.utils.toWei("10000"); - const rate = 1000; - const fundRaiseType = [0]; - const budget = 0; - const maxCost = STOSetupCost; - const cappedBytesSig = encodeModuleCall(CappedSTOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, 'Hello']); - const presaleBytesSig = encodeModuleCall(PresaleSTOParameters, [endTime]); - - for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { - await I_PolyToken.getTokens(STOSetupCost, account_issuer); - await I_PolyToken.transfer(I_SecurityToken.address, STOSetupCost, { from: account_issuer }); - switch (STOIndex % 3) { - case 0: - // Capped STO - let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { from: account_issuer }); - assert.equal(tx1.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx1.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); - I_STO_Array.push(CappedSTO.at(tx1.logs[3].args._module)); - break; - case 1: - // Dummy STO - let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { from: account_issuer }); - assert.equal(tx2.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx2.logs[3].args._name),"DummySTO",`Wrong STO module added at index ${STOIndex}`); - I_STO_Array.push(DummySTO.at(tx2.logs[3].args._module)); - break; - case 2: - // Pre Sale STO - let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { from: account_issuer }); - assert.equal(tx3.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx3.logs[3].args._name),"PreSaleSTO",`Wrong STO module added at index ${STOIndex}`); - I_STO_Array.push(PreSaleSTO.at(tx3.logs[3].args._module)); - break; - } - } - - }); - - it("Should successfully invest in all modules attached", async() => { - const MAX_MODULES = 10; - await increaseTime(duration.days(2)); - for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { - switch (STOIndex % 3) { - case 0: - // Capped STO ETH - await I_STO_Array[STOIndex].buyTokens(account_investor1, { from : account_investor1, value: web3.utils.toWei('1', 'ether') }); - assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); - assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); - break; - case 1: - // Dummy STO - await I_STO_Array[STOIndex].generateTokens(account_investor1, web3.utils.toWei('1000'), { from : account_issuer }); - assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); - assert.equal( - (await I_STO_Array[STOIndex].investors.call(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - break; - case 2: - // Pre Sale STO - await I_STO_Array[STOIndex].allocateTokens(account_investor1, web3.utils.toWei('1000'), web3.utils.toWei('1'), 0, { from : account_issuer }); - assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); - assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(1)).toString()), 0); - assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); - assert.equal( - (await I_STO_Array[STOIndex].investors.call(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - break; - } - } - }); + it('Should whitelist account_investor1', async () => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let canBuyFromSTO = true; + + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, canBuyFromSTO, { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); + }); + }); + + describe('Add STO and verify transfer', async () => { + it('Should attach STO modules up to the max number, then fail', async () => { + const MAX_MODULES = 10; + const startTime = latestTime() + duration.days(1); + const endTime = latestTime() + duration.days(90); + const cap = web3.utils.toWei('10000'); + const rate = 1000; + const fundRaiseType = [0]; + const budget = 0; + const maxCost = STOSetupCost; + const cappedBytesSig = encodeModuleCall(CappedSTOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, 'Hello']); + const presaleBytesSig = encodeModuleCall(PresaleSTOParameters, [endTime]); + + for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { + await I_PolyToken.getTokens(STOSetupCost, account_issuer); + await I_PolyToken.transfer(I_SecurityToken.address, STOSetupCost, { from: account_issuer }); + switch (STOIndex % 3) { + case 0: + // Capped STO + let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { + from: account_issuer + }); + assert.equal(tx1.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx1.logs[3].args._name), 'CappedSTO', `Wrong STO module added at index ${STOIndex}`); + I_STO_Array.push(CappedSTO.at(tx1.logs[3].args._module)); + break; + case 1: + // Dummy STO + let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { from: account_issuer }); + assert.equal(tx2.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx2.logs[3].args._name), 'DummySTO', `Wrong STO module added at index ${STOIndex}`); + I_STO_Array.push(DummySTO.at(tx2.logs[3].args._module)); + break; + case 2: + // Pre Sale STO + let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { + from: account_issuer + }); + assert.equal(tx3.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx3.logs[3].args._name), 'PreSaleSTO', `Wrong STO module added at index ${STOIndex}`); + I_STO_Array.push(PreSaleSTO.at(tx3.logs[3].args._module)); + break; + } + } + }); + + it('Should successfully invest in all modules attached', async () => { + const MAX_MODULES = 10; + await increaseTime(duration.days(2)); + for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { + switch (STOIndex % 3) { + case 0: + // Capped STO ETH + await I_STO_Array[STOIndex].buyTokens(account_investor1, { from: account_investor1, value: web3.utils.toWei('1', 'ether') }); + assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); + assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); + break; + case 1: + // Dummy STO + await I_STO_Array[STOIndex].generateTokens(account_investor1, web3.utils.toWei('1000'), { from: account_issuer }); + assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); + assert.equal( + (await I_STO_Array[STOIndex].investors.call(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 1000 + ); + break; + case 2: + // Pre Sale STO + await I_STO_Array[STOIndex].allocateTokens(account_investor1, web3.utils.toWei('1000'), web3.utils.toWei('1'), 0, { + from: account_issuer + }); + assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); + assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(1)).toString()), 0); + assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); + assert.equal( + (await I_STO_Array[STOIndex].investors.call(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 1000 + ); + break; + } + } }); + }); }); diff --git a/test/s_v130_to_v140_upgrade.js b/test/s_v130_to_v140_upgrade.js index 4db50ca9f..d710d17f0 100644 --- a/test/s_v130_to_v140_upgrade.js +++ b/test/s_v130_to_v140_upgrade.js @@ -1,12 +1,12 @@ const Web3 = require('web3'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port const BigNumber = require('bignumber.js'); import latestTime from './helpers/latestTime'; import { duration } from './helpers/utils'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const USDTieredSTOProxyFactory = artifacts.require('./USDTieredSTOProxyFactory.sol'); const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); @@ -27,238 +27,235 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const ManualApprovalTransferManagerFactory = artifacts.require('./ManualApprovalTransferManagerFactory.sol'); contract('Upgrade from v1.3.0 to v1.4.0', accounts => { - // Accounts Variable declaration - let POLYMATH; - let ISSUER1; - let ISSUER2; - let ISSUER3; - let MULTISIG; - - //const GAS_PRICE = 10000000000; // 10 GWEI - - let tx; - - // Initial fee for ticker registry and security token registry - const REGFEE = web3.utils.toWei("250"); - const STOSetupCost = 0; - - // Module key - const STOKEY = 3; - const TMKEY = 2; - - // SecurityToken 1 Details - const symbol1 = "TOK1"; - const name1 = "TOK1 Token"; - const tokenDetails1 = "This is equity type of issuance"; - - //SecurityToken 2 Details - const symbol2 = "TOK2"; - const name2 = "TOK2 Token"; - const tokenDetails2 = "This is equity type of issuance"; - - //SecurityToken 3 Details - const symbol3 = "TOK3"; - const name3 = "TOK3 Token"; - const tokenDetails3 = "This is equity type of issuance"; - - // Contract Instance Declaration - let I_PolymathRegistry; - let I_PolyToken; - let I_DaiToken; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_FeatureRegistry; - let I_STFactory; - let I_MRProxied; - let I_STRProxied; - let I_STRProxiedNew; - - let I_SecurityTokenRegistry; - //let I_UpgradedSecurityTokenRegistry - - let I_SecurityToken1; - let I_SecurityToken2; - //let I_SecurityToken3; - - let I_USDTieredSTOFactory; - let I_USDTieredSTOProxyFactory - let I_USDOracle; - let I_POLYOracle; - let I_USDTieredSTO; - - let I_CappedSTOFactory; - let I_UpgradedCappedSTOFactory; - let I_CappedSTO; - let I_ManualApprovalTransferManagerFactory; - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - // Prepare polymath network status - before(async() => { - // Accounts setup - POLYMATH = accounts[0]; - ISSUER1 = accounts[1]; - ISSUER2 = accounts[2]; - ISSUER3 = accounts[3]; - MULTISIG = accounts[4]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); - assert.notEqual( - I_PolymathRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PolymathRegistry contract was not deployed" - ); - - // Step 1: Deploy the token Faucet - I_PolyToken = await PolyTokenFaucet.new({from: POLYMATH}); - I_DaiToken = await PolyTokenFaucet.new({from: POLYMATH}); - assert.notEqual( - I_PolyToken.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PolyToken contract was not deployed" - ); - tx = await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) - assert.equal(tx.logs[0].args._nameKey, "PolyToken"); - assert.equal(tx.logs[0].args._newAddress, I_PolyToken.address); - - // STEP 2: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - tx = await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); - assert.equal(tx.logs[0].args._nameKey, "ModuleRegistry"); - assert.equal(tx.logs[0].args._newAddress, I_ModuleRegistryProxy.address); - - // STEP 3: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the CappedSTOFactory - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // 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_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_STRProxied.address, {from: POLYMATH}); - await I_MRProxied.updateFromRegistry({from: POLYMATH}); - - // STEP 6: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - - // (C) : Register the CappedSTOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: POLYMATH }); - - // 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 13: Register tokens - // (A) : TOK1 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); - tx = await I_STRProxied.registerTicker(ISSUER1, symbol1, name1, { from : ISSUER1 }); - assert.equal(tx.logs[0].args._owner, ISSUER1); - assert.equal(tx.logs[0].args._ticker, symbol1); - - // (B) : TOK2 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); - tx = await I_STRProxied.registerTicker(ISSUER2, symbol2, name2, { from : ISSUER2 }); - assert.equal(tx.logs[0].args._owner, ISSUER2); - assert.equal(tx.logs[0].args._ticker, symbol2); - - // (C) : TOK3 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER3 }); - tx = await I_STRProxied.registerTicker(ISSUER3, symbol3, name3, { from : ISSUER3 }); - assert.equal(tx.logs[0].args._owner, ISSUER3); - assert.equal(tx.logs[0].args._ticker, symbol3); - - // Step 14: Deploy tokens - // (A) : TOK1 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1}); - let tx = await I_STRProxied.generateSecurityToken(name1, symbol1, tokenDetails1, false, { from: ISSUER1 }); - assert.equal(tx.logs[1].args._ticker, symbol1, "SecurityToken doesn't get deployed"); - I_SecurityToken1 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - // (B) : TOK2 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2}); - tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails2, false, { from: ISSUER2 }); - assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); - I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let POLYMATH; + let ISSUER1; + let ISSUER2; + let ISSUER3; + let MULTISIG; + + //const GAS_PRICE = 10000000000; // 10 GWEI + + let tx; + + // Initial fee for ticker registry and security token registry + const REGFEE = web3.utils.toWei('250'); + const STOSetupCost = 0; + + // Module key + const STOKEY = 3; + const TMKEY = 2; + + // SecurityToken 1 Details + const symbol1 = 'TOK1'; + const name1 = 'TOK1 Token'; + const tokenDetails1 = 'This is equity type of issuance'; + + //SecurityToken 2 Details + const symbol2 = 'TOK2'; + const name2 = 'TOK2 Token'; + const tokenDetails2 = 'This is equity type of issuance'; + + //SecurityToken 3 Details + const symbol3 = 'TOK3'; + const name3 = 'TOK3 Token'; + const tokenDetails3 = 'This is equity type of issuance'; + + // Contract Instance Declaration + let I_PolymathRegistry; + let I_PolyToken; + let I_DaiToken; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_FeatureRegistry; + let I_STFactory; + let I_MRProxied; + let I_STRProxied; + let I_STRProxiedNew; + + let I_SecurityTokenRegistry; + //let I_UpgradedSecurityTokenRegistry + + let I_SecurityToken1; + let I_SecurityToken2; + //let I_SecurityToken3; + + let I_USDTieredSTOFactory; + let I_USDTieredSTOProxyFactory; + let I_USDOracle; + let I_POLYOracle; + let I_USDTieredSTO; + + let I_CappedSTOFactory; + let I_UpgradedCappedSTOFactory; + let I_CappedSTO; + let I_ManualApprovalTransferManagerFactory; + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + // Prepare polymath network status + before(async () => { + // Accounts setup + POLYMATH = accounts[0]; + ISSUER1 = accounts[1]; + ISSUER2 = accounts[2]; + ISSUER3 = accounts[3]; + MULTISIG = accounts[4]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); + assert.notEqual( + I_PolymathRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'PolymathRegistry contract was not deployed' + ); + + // Step 1: Deploy the token Faucet + I_PolyToken = await PolyTokenFaucet.new({ from: POLYMATH }); + I_DaiToken = await PolyTokenFaucet.new({ from: POLYMATH }); + assert.notEqual(I_PolyToken.address.valueOf(), '0x0000000000000000000000000000000000000000', 'PolyToken contract was not deployed'); + tx = await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._nameKey, 'PolyToken'); + assert.equal(tx.logs[0].args._newAddress, I_PolyToken.address); + + // STEP 2: Deploy the ModuleRegistry + I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + tx = await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._nameKey, 'ModuleRegistry'); + assert.equal(tx.logs[0].args._newAddress, I_ModuleRegistryProxy.address); + + // STEP 3: Deploy the GeneralTransferManagerFactory + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); + + // STEP 4: Deploy the GeneralDelegateManagerFactory + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); + + // STEP 5: Deploy the CappedSTOFactory + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CappedSTOFactory contract was not deployed' + ); + + // Step 8: Deploy the STFactory contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + + // Step 9: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + // Step 10: update the registries addresses from the PolymathRegistry contract + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + REGFEE, + REGFEE, + I_PolyToken.address, + POLYMATH + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // 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_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_STRProxied.address, { from: POLYMATH }); + await I_MRProxied.updateFromRegistry({ from: POLYMATH }); + + // STEP 6: Register the Modules with the ModuleRegistry contract + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); + + // (C) : Register the CappedSTOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: POLYMATH }); + + // 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 13: Register tokens + // (A) : TOK1 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); + tx = await I_STRProxied.registerTicker(ISSUER1, symbol1, name1, { from: ISSUER1 }); + assert.equal(tx.logs[0].args._owner, ISSUER1); + assert.equal(tx.logs[0].args._ticker, symbol1); + + // (B) : TOK2 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); + tx = await I_STRProxied.registerTicker(ISSUER2, symbol2, name2, { from: ISSUER2 }); + assert.equal(tx.logs[0].args._owner, ISSUER2); + assert.equal(tx.logs[0].args._ticker, symbol2); + + // (C) : TOK3 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER3 }); + tx = await I_STRProxied.registerTicker(ISSUER3, symbol3, name3, { from: ISSUER3 }); + assert.equal(tx.logs[0].args._owner, ISSUER3); + assert.equal(tx.logs[0].args._ticker, symbol3); + + // Step 14: Deploy tokens + // (A) : TOK1 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); + let tx = await I_STRProxied.generateSecurityToken(name1, symbol1, tokenDetails1, false, { from: ISSUER1 }); + assert.equal(tx.logs[1].args._ticker, symbol1, "SecurityToken doesn't get deployed"); + I_SecurityToken1 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + // (B) : TOK2 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); + tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails2, false, { from: ISSUER2 }); + assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); + I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -275,113 +272,111 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { SecurityToken TOK2: ${I_SecurityToken2.address} ----------------------------------------------------------------------------- `); + }); + + describe('USDTieredSTOFactory deploy', async () => { + // Step 1: Deploy Oracles + // 1a - Deploy POLY Oracle + it('Should successfully deploy POLY Oracle and register on PolymathRegistry', async () => { + I_POLYOracle = await PolyOracle.new({ from: POLYMATH, value: web3.utils.toWei('1') }); + console.log(I_POLYOracle.address); + assert.notEqual(I_POLYOracle.address.valueOf(), '0x0000000000000000000000000000000000000000', 'POLYOracle contract was not deployed'); + tx = await I_PolymathRegistry.changeAddress('PolyUsdOracle', I_POLYOracle.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._nameKey, 'PolyUsdOracle'); + assert.equal(tx.logs[0].args._newAddress, I_POLYOracle.address); }); - - describe("USDTieredSTOFactory deploy", async() => { - // Step 1: Deploy Oracles - // 1a - Deploy POLY Oracle - it("Should successfully deploy POLY Oracle and register on PolymathRegistry", async() => { - I_POLYOracle = await PolyOracle.new({ from: POLYMATH, value: web3.utils.toWei("1")}); - console.log(I_POLYOracle.address); - assert.notEqual( - I_POLYOracle.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "POLYOracle contract was not deployed", - ); - tx = await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, "PolyUsdOracle"); - assert.equal(tx.logs[0].args._newAddress, I_POLYOracle.address); - }); - // 1b - Deploy ETH Oracle - it("Should successfully deploy ETH Oracle and register on PolymathRegistry", async() => { - I_USDOracle = await ETHOracle.new("0x216d678c14be600cb88338e763bb57755ca2b1cf", "0x0000000000000000000000000000000000000000", "ETH", { from: POLYMATH }); - assert.notEqual( - I_USDOracle.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "USDOracle contract was not deployed", - ); - tx = await I_PolymathRegistry.changeAddress("EthUsdOracle", I_USDOracle.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, "EthUsdOracle"); - assert.equal(tx.logs[0].args._newAddress, I_USDOracle.address); - }); + // 1b - Deploy ETH Oracle + it('Should successfully deploy ETH Oracle and register on PolymathRegistry', async () => { + I_USDOracle = await ETHOracle.new('0x216d678c14be600cb88338e763bb57755ca2b1cf', '0x0000000000000000000000000000000000000000', 'ETH', { + from: POLYMATH + }); + assert.notEqual(I_USDOracle.address.valueOf(), '0x0000000000000000000000000000000000000000', 'USDOracle contract was not deployed'); + tx = await I_PolymathRegistry.changeAddress('EthUsdOracle', I_USDOracle.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._nameKey, 'EthUsdOracle'); + assert.equal(tx.logs[0].args._newAddress, I_USDOracle.address); }); - - describe("USDTieredSTOFactory deploy", async() => { - // Step 1: Deploy USDTieredSTOFactory\ - it("Should successfully deploy USDTieredSTOFactory", async() => { - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new(); - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: POLYMATH }); - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "USDTieredSTOFactory contract was not deployed" - ); - let setupCost = await I_USDTieredSTOFactory.setupCost({ from: POLYMATH }); - assert.equal(setupCost, STOSetupCost); - }); - // Step 2: Register and verify - it("Should successfully register and verify USDTieredSTOFactory contract", async() => { - let tx = await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); - tx = await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); - assert.isTrue(tx.logs[0].args._verified); - }); + }); + + describe('USDTieredSTOFactory deploy', async () => { + // Step 1: Deploy USDTieredSTOFactory\ + it('Should successfully deploy USDTieredSTOFactory', async () => { + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new(); + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { + from: POLYMATH + }); + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'USDTieredSTOFactory contract was not deployed' + ); + let setupCost = await I_USDTieredSTOFactory.setupCost({ from: POLYMATH }); + assert.equal(setupCost, STOSetupCost); + }); + // Step 2: Register and verify + it('Should successfully register and verify USDTieredSTOFactory contract', async () => { + let tx = await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); + tx = await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); + assert.isTrue(tx.logs[0].args._verified); + }); + }); + + describe('CappedSTOFactory deploy', async () => { + // Step 1: Deploy new CappedSTOFactory + it('Should successfully deploy CappedSTOFactory', async () => { + I_UpgradedCappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_UpgradedCappedSTOFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'CappedSTOFactory contract was not deployed' + ); + let setupCost = await I_UpgradedCappedSTOFactory.setupCost({ from: POLYMATH }); + assert.equal(setupCost, STOSetupCost); }); - describe("CappedSTOFactory deploy", async() => { - // Step 1: Deploy new CappedSTOFactory - it("Should successfully deploy CappedSTOFactory", async() => { - I_UpgradedCappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_UpgradedCappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); - let setupCost = await I_UpgradedCappedSTOFactory.setupCost({ from: POLYMATH }); - assert.equal(setupCost, STOSetupCost); - }); - - // Step 2: Register and verify - it("Should successfully register and verify new CappedSTOFactory contract", async() => { - let tx = await I_MRProxied.registerModule(I_UpgradedCappedSTOFactory.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); - tx = await I_MRProxied.verifyModule(I_UpgradedCappedSTOFactory.address, true, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); - assert.isTrue(tx.logs[0].args._verified); - }); - - // Step 3: Unverify old CappedSTOFactory - it("Should successfully unverify old CappedSTOFactory contract", async() => { - let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory.address, false, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory.address); - assert.isFalse(tx.logs[0].args._verified); - }); + // Step 2: Register and verify + it('Should successfully register and verify new CappedSTOFactory contract', async () => { + let tx = await I_MRProxied.registerModule(I_UpgradedCappedSTOFactory.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); + tx = await I_MRProxied.verifyModule(I_UpgradedCappedSTOFactory.address, true, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); + assert.isTrue(tx.logs[0].args._verified); }); - describe("ManualApprovalTransferManagerFactory deploy", async() => { - // Step 1: Deploy new ManualApprovalTransferManager - it("Should successfully deploy ManualApprovalTransferManagerFactory", async() => { - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_ManualApprovalTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ManualApprovalTransferManagerFactory contract was not deployed" - ); - }); + // Step 3: Unverify old CappedSTOFactory + it('Should successfully unverify old CappedSTOFactory contract', async () => { + let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory.address, false, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory.address); + assert.isFalse(tx.logs[0].args._verified); + }); + }); + + describe('ManualApprovalTransferManagerFactory deploy', async () => { + // Step 1: Deploy new ManualApprovalTransferManager + it('Should successfully deploy ManualApprovalTransferManagerFactory', async () => { + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: POLYMATH + }); + assert.notEqual( + I_ManualApprovalTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'ManualApprovalTransferManagerFactory contract was not deployed' + ); + }); - // Step 2: Register and verify - it("Should successfully register and verify new ManualApprovalTransferManagerFactory contract", async() => { - let tx = await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); - tx = await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); - assert.isTrue(tx.logs[0].args._verified); - }); + // Step 2: Register and verify + it('Should successfully register and verify new ManualApprovalTransferManagerFactory contract', async () => { + let tx = await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); + tx = await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); + assert.isTrue(tx.logs[0].args._verified); }); + }); - describe("Change ownerships", async() => { - /* + describe('Change ownerships', async () => { + /* // Step 1: SecurityTokenRegistry it("Should successfully change ownership of new SecurityTokenRegistry contract", async() => { let tx = await I_STRProxiedNew.transferOwnership(MULTISIG, { from: POLYMATH }); @@ -390,112 +385,134 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); */ - // Step 2: Oracles - it("Should successfully change ownership of both Oracles contract", async() => { - let tx = await I_USDOracle.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous ETH Oracle owner was not Polymath account"); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New ETH Oracle owner is not Multisig account"); - - tx = await I_POLYOracle.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous POLY Oracle owner was not Polymath account"); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New POLY Oracle owner is not Multisig account"); - }); + // Step 2: Oracles + it('Should successfully change ownership of both Oracles contract', async () => { + let tx = await I_USDOracle.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous ETH Oracle owner was not Polymath account'); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New ETH Oracle owner is not Multisig account'); - // Step 3: USDTieredSTOFactory - it("Should successfully change ownership of USDTieredSTOFactory contract", async() => { - let tx = await I_USDTieredSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous USDTieredSTOFactory owner was not Polymath account"); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New USDTieredSTOFactory owner is not Multisig account"); - }); + tx = await I_POLYOracle.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous POLY Oracle owner was not Polymath account'); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New POLY Oracle owner is not Multisig account'); + }); - // Step 3: CappedSTOFactory - it("Should successfully change ownership of CappedSTOFactory contract", async() => { - let tx = await I_UpgradedCappedSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous USDTieredSTOFactory owner was not Polymath account"); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New USDTieredSTOFactory owner is not Multisig account"); - }); + // Step 3: USDTieredSTOFactory + it('Should successfully change ownership of USDTieredSTOFactory contract', async () => { + let tx = await I_USDTieredSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous USDTieredSTOFactory owner was not Polymath account'); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New USDTieredSTOFactory owner is not Multisig account'); + }); - // Step 4: ManualApprovalTransferManagerFactory - it("Should successfully change ownership of ManualApprovalTransferManagerFactory contract", async() => { - let tx = await I_ManualApprovalTransferManagerFactory.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous ManualApprovalTransferManagerFactory owner was not Polymath account"); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New ManualApprovalTransferManagerFactory owner is not Multisig account"); - }); + // Step 3: CappedSTOFactory + it('Should successfully change ownership of CappedSTOFactory contract', async () => { + let tx = await I_UpgradedCappedSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous USDTieredSTOFactory owner was not Polymath account'); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New USDTieredSTOFactory owner is not Multisig account'); }); - describe("Polymath network status post migration", async() => { - // Launch STO for TOK1 - it("Should successfully launch USDTieredSTO for first security token", async() => { - let _startTime = latestTime() + duration.days(1); - let _endTime = _startTime + duration.days(180); - let _ratePerTier = [BigNumber(0.1).mul(10**18), BigNumber(0.15).mul(10**18), BigNumber(0.2).mul(10**18)]; - let _ratePerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; - let _tokensPerTierTotal = [BigNumber(100).mul(10**18), BigNumber(200).mul(10**18), BigNumber(300).mul(10**18)]; - let _tokensPerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; - let _nonAccreditedLimitUSD = BigNumber(100).mul(10**18); - let _minimumInvestmentUSD = BigNumber(5).mul(10**18); - let _fundRaiseTypes = [0, 1]; - let _wallet = ISSUER1; - let _reserveWallet = ISSUER1; - let _usdToken = I_DaiToken.address; - - let config = [ - _startTime, _endTime, _ratePerTier, _ratePerTierDiscountPoly, _tokensPerTierTotal, - _tokensPerTierDiscountPoly, _nonAccreditedLimitUSD, _minimumInvestmentUSD, - _fundRaiseTypes, _wallet, _reserveWallet, _usdToken - ]; - - let functionSignature = { - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_startTime' - },{ - type: 'uint256', - name: '_endTime' - },{ - type: 'uint256[]', - name: '_ratePerTier' - },{ - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - },{ - type: 'uint256[]', - name: '_tokensPerTier' - },{ - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - },{ - type: 'uint256', - name: '_nonAccreditedLimitUSD' - },{ - type: 'uint256', - name: '_minimumInvestmentUSD' - },{ - type: 'uint8[]', - name: '_fundRaiseTypes' - },{ - type: 'address', - name: '_wallet' - },{ - type: 'address', - name: '_reserveWallet' - },{ - type: 'address', - name: '_usdToken' - }] - }; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - let tx = await I_SecurityToken1.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER1 }); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); - I_USDTieredSTO = USDTieredSTO.at(tx.logs[2].args._module); - }); + // Step 4: ManualApprovalTransferManagerFactory + it('Should successfully change ownership of ManualApprovalTransferManagerFactory contract', async () => { + let tx = await I_ManualApprovalTransferManagerFactory.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous ManualApprovalTransferManagerFactory owner was not Polymath account'); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New ManualApprovalTransferManagerFactory owner is not Multisig account'); + }); + }); + + describe('Polymath network status post migration', async () => { + // Launch STO for TOK1 + it('Should successfully launch USDTieredSTO for first security token', async () => { + let _startTime = latestTime() + duration.days(1); + let _endTime = _startTime + duration.days(180); + let _ratePerTier = [BigNumber(0.1).mul(10 ** 18), BigNumber(0.15).mul(10 ** 18), BigNumber(0.2).mul(10 ** 18)]; + let _ratePerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; + let _tokensPerTierTotal = [BigNumber(100).mul(10 ** 18), BigNumber(200).mul(10 ** 18), BigNumber(300).mul(10 ** 18)]; + let _tokensPerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; + let _nonAccreditedLimitUSD = BigNumber(100).mul(10 ** 18); + let _minimumInvestmentUSD = BigNumber(5).mul(10 ** 18); + let _fundRaiseTypes = [0, 1]; + let _wallet = ISSUER1; + let _reserveWallet = ISSUER1; + let _usdToken = I_DaiToken.address; + + let config = [ + _startTime, + _endTime, + _ratePerTier, + _ratePerTierDiscountPoly, + _tokensPerTierTotal, + _tokensPerTierDiscountPoly, + _nonAccreditedLimitUSD, + _minimumInvestmentUSD, + _fundRaiseTypes, + _wallet, + _reserveWallet, + _usdToken + ]; + + let functionSignature = { + name: 'configure', + type: 'function', + inputs: [ + { + type: 'uint256', + name: '_startTime' + }, + { + type: 'uint256', + name: '_endTime' + }, + { + type: 'uint256[]', + name: '_ratePerTier' + }, + { + type: 'uint256[]', + name: '_ratePerTierDiscountPoly' + }, + { + type: 'uint256[]', + name: '_tokensPerTier' + }, + { + type: 'uint256[]', + name: '_tokensPerTierDiscountPoly' + }, + { + type: 'uint256', + name: '_nonAccreditedLimitUSD' + }, + { + type: 'uint256', + name: '_minimumInvestmentUSD' + }, + { + type: 'uint8[]', + name: '_fundRaiseTypes' + }, + { + type: 'address', + name: '_wallet' + }, + { + type: 'address', + name: '_reserveWallet' + }, + { + type: 'address', + name: '_usdToken' + } + ] + }; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + let tx = await I_SecurityToken1.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER1 }); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); + I_USDTieredSTO = USDTieredSTO.at(tx.logs[2].args._module); + }); - /* + /* // Deploy TOK3 it("Should successfully deploy third security token", async() => { await I_PolyToken.approve(I_STRProxiedNew.address, REGFEE, { from: ISSUER3}); @@ -505,28 +522,32 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); */ - // Launch NewCappedSTO for TOK2 - it("Should successfully launch CappedSTO for third security token", async() => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - let cap = web3.utils.toWei("500000"); - let rate = 1000; - let fundRaiseType = 0; - let fundsReceiver = ISSUER3; + // Launch NewCappedSTO for TOK2 + it('Should successfully launch CappedSTO for third security token', async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + let cap = web3.utils.toWei('500000'); + let rate = 1000; + let fundRaiseType = 0; + let fundsReceiver = ISSUER3; - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [fundRaiseType], fundsReceiver]); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [fundRaiseType], fundsReceiver]); - let tx = await I_SecurityToken2.addModule(I_UpgradedCappedSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER2 }); - assert.equal(tx.logs[2].args._type, STOKEY, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"CappedSTO","CappedSTOFactory module was not added"); - }); + let tx = await I_SecurityToken2.addModule(I_UpgradedCappedSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER2 }); + assert.equal(tx.logs[2].args._type, STOKEY, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); + }); - // Attach ManualApprovalTransferManager module for TOK2 - it("Should successfully attach the ManualApprovalTransferManagerFactory with the second token", async () => { - const tx = await I_SecurityToken2.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: ISSUER2 }); - assert.equal(tx.logs[2].args._type.toNumber(), TMKEY, "ManualApprovalTransferManagerFactory doesn't get deployed"); - assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManagerFactory module was not added"); - I_ManualApprovalTransferManagerFactory = ManualApprovalTransferManagerFactory.at(tx.logs[2].args._module); - }); + // Attach ManualApprovalTransferManager module for TOK2 + it('Should successfully attach the ManualApprovalTransferManagerFactory with the second token', async () => { + const tx = await I_SecurityToken2.addModule(I_ManualApprovalTransferManagerFactory.address, '', 0, 0, { from: ISSUER2 }); + assert.equal(tx.logs[2].args._type.toNumber(), TMKEY, "ManualApprovalTransferManagerFactory doesn't get deployed"); + assert.equal( + web3.utils.toUtf8(tx.logs[2].args._name), + 'ManualApprovalTransferManager', + 'ManualApprovalTransferManagerFactory module was not added' + ); + I_ManualApprovalTransferManagerFactory = ManualApprovalTransferManagerFactory.at(tx.logs[2].args._module); }); + }); }); diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 91ef0c974..65513d600 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -2,292 +2,300 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); -const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); -const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); +const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); +const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); +const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); +const SecurityTokenRegistryMock = artifacts.require('./SecurityTokenRegistryMock.sol'); const OwnedUpgradeabilityProxy = artifacts.require('./OwnedUpgradeabilityProxy.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol') -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const STFactory = artifacts.require('./STFactory.sol'); const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol') +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port + +contract('SecurityTokenRegistryProxy', accounts => { + let I_SecurityTokenRegistry; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryMock; + let I_STFactory; + let I_PolymathRegistry; + let I_ModuleRegistryProxy; + let I_PolyToken; + let I_STRProxied; + let I_MRProxied; + let I_SecurityToken; + let I_ModuleRegistry; + let I_FeatureRegistry; + + let account_polymath; + let account_temp; + let token_owner; + let account_polymath_new; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + const version = '1.0.0'; + const message = 'Transaction Should Fail!'; + + // SecurityToken Details for funds raise Type ETH + const name = 'Team'; + const symbol = 'SAP'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + const transferManagerKey = 2; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + async function readStorage(contractAddress, slot) { + return await web3.eth.getStorageAt(contractAddress, slot); + } + + before(async () => { + account_polymath = accounts[0]; + account_temp = accounts[1]; + token_owner = accounts[2]; + account_polymath_new = accounts[3]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); -contract ("SecurityTokenRegistryProxy", accounts => { + // STEP 3: Deploy the ModuleRegistry + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - let I_SecurityTokenRegistry; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryMock; - let I_STFactory; - let I_PolymathRegistry; - let I_ModuleRegistryProxy; - let I_PolyToken; - let I_STRProxied; - let I_MRProxied; - let I_SecurityToken; - let I_ModuleRegistry; - let I_FeatureRegistry; + // STEP 4: Deploy the GeneralTransferManagerFactory - let account_polymath; - let account_temp; - let token_owner; - let account_polymath_new; + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - const version = "1.0.0"; - const message = "Transaction Should Fail!"; + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - // SecurityToken Details for funds raise Type ETH - const name = "Team"; - const symbol = "SAP"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; + // Register the Modules with the ModuleRegistry contract - const transferManagerKey = 2; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + // Step 3: Deploy the STFactory contract - async function readStorage(contractAddress, slot) { - return await web3.eth.getStorageAt(contractAddress, slot); - } + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - before(async() => { - account_polymath = accounts[0]; - account_temp = accounts[1]; - token_owner = accounts[2]; - account_polymath_new = accounts[3]; + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - // ----------- POLYMATH NETWORK Configuration ------------ + // Step 4: Deploy the SecurityTokenRegistry + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - // Step 2: Deploy the FeatureRegistry + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} - // STEP 3: Deploy the ModuleRegistry + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + ----------------------------------------------------------------------------- + `); + }); + + describe('Attach the implementation address', async () => { + // Storage + // __version -- index 11 + // __implementation -- index 12 + // __upgradeabilityOwner -- index 13 + + it('Should attach the implementation and version', async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); + assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, '') + .replace(/\n/, ''), + '1.0.0' + ); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + }); + + it('Verify the initialize data', async () => { + assert.equal( + (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('expiryLimit'))).toNumber(), + 60 * 24 * 60 * 60, + 'Should equal to 60 days' + ); + assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('tickerRegFee'))).toNumber(), web3.utils.toWei('250')); + }); + }); + + describe('Feed some data in storage', async () => { + it('Register the ticker', async () => { + await I_PolyToken.getTokens(web3.utils.toWei('1000'), token_owner); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, 'Owner should be the same as registered with the ticker'); + assert.equal(tx.logs[0].args._ticker, symbol, 'Same as the symbol registered in the registerTicker function call'); + }); - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - // STEP 4: Deploy the GeneralTransferManagerFactory + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - // Register the Modules with the ModuleRegistry contract + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); + }); + }); + + describe('Upgrade the imlplementation address', async () => { + it('Should upgrade the version and implementation address -- fail bad owner', async () => { + I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({ from: account_polymath }); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryMock.address, { from: account_temp })); + }); + it('Should upgrade the version and implementation address -- Implementaion address should be a contract address', async () => { + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', account_temp, { from: account_polymath })); + }); - // Step 3: Deploy the STFactory contract + it('Should upgrade the version and implementation address -- Implemenation address should not be 0x', async () => { + await catchRevert( + I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', '0x00000000000000000000000000000000000000', { from: account_polymath }) + ); + }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + it('Should upgrade the version and implementation address -- Implemenation address should not be the same address', async () => { + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistry.address, { from: account_polymath })); + }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + it('Should upgrade the version and implementation address -- same version as previous is not allowed', async () => { + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.0.0', I_SecurityTokenRegistryMock.address, { from: account_polymath })); + }); - // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + it('Should upgrade the version and implementation address -- empty version string is not allowed', async () => { + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('', I_SecurityTokenRegistryMock.address, { from: account_polymath })); + }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + it('Should upgrade the version and the implementation address successfully', async () => { + await I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryMock.address, { from: account_polymath }); + let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, '') + .replace(/\n/, ''), + '1.1.0', + 'Version mis-match' + ); + assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistryMock.address, 'Implemnted address is not matched'); + I_STRProxied = await SecurityTokenRegistryMock.at(I_SecurityTokenRegistryProxy.address); + }); + }); + + describe('Execute functionality of the implementation contract on the earlier storage', async () => { + it('Should get the previous data', async () => { + let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); + let _data = await I_STRProxied.getSecurityTokenData.call(_tokenAddress); + assert.equal(_data[0], symbol, 'Symbol should match with registered symbol'); + assert.equal(_data[1], token_owner, 'Owner should be the deployer of token'); + assert.equal(_data[2], tokenDetails, 'Token details should matched with deployed ticker'); + }); + it('Should alter the old storage', async () => { + await I_STRProxied.changeTheDeployedAddress(symbol, account_temp, { from: account_polymath }); + let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); + assert.equal(_tokenAddress, account_temp, 'Should match with the changed address'); + }); + }); - // Printing all the contract addresses - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} + describe('Transfer the ownership of the proxy contract', async () => { + it('Should change the ownership of the contract -- because of bad owner', async () => { + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_temp })); + }); - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - ----------------------------------------------------------------------------- - `); + it('Should change the ownership of the contract -- new address should not be 0x', async () => { + await catchRevert( + I_SecurityTokenRegistryProxy.transferProxyOwnership('0x00000000000000000000000000000000000000', { from: account_polymath }) + ); }); - describe("Attach the implementation address", async() => { - - // Storage - // __version -- index 11 - // __implementation -- index 12 - // __upgradeabilityOwner -- index 13 - - it("Should attach the implementation and version", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.0.0"); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - }); - - it("Verify the initialize data", async() => { - assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))).toNumber(), 60*24*60*60, "Should equal to 60 days"); - assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("tickerRegFee"))).toNumber(), web3.utils.toWei("250")); - }); - - }) - - describe("Feed some data in storage", async() => { - - it("Register the ticker", async() => { - await I_PolyToken.getTokens(web3.utils.toWei("1000"), token_owner); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, "Owner should be the same as registered with the ticker"); - assert.equal(tx.logs[0].args._ticker, symbol, "Same as the symbol registered in the registerTicker function call"); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); - }); - }) - - describe("Upgrade the imlplementation address", async() => { - - it("Should upgrade the version and implementation address -- fail bad owner", async() => { - - I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({from: account_polymath}); - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_temp})); - }); - - it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); - }); - - it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); - }); - - it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistry.address, {from: account_polymath})); - }); - - it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.0.0", I_SecurityTokenRegistryMock.address, {from: account_polymath})); - }); - - it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("", I_SecurityTokenRegistryMock.address, {from: account_polymath})); - }); - - it("Should upgrade the version and the implementation address successfully", async() => { - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_polymath}); - let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.1.0", "Version mis-match"); - assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistryMock.address, "Implemnted address is not matched"); - I_STRProxied = await SecurityTokenRegistryMock.at(I_SecurityTokenRegistryProxy.address); - }); + it('Should change the ownership of the contract', async () => { + await I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_polymath }); + let _currentOwner = await I_SecurityTokenRegistryProxy.proxyOwner.call({ from: account_polymath_new }); + assert.equal(_currentOwner, account_polymath_new, 'Should equal to the new owner'); }); - describe("Execute functionality of the implementation contract on the earlier storage", async() => { - - it("Should get the previous data", async() => { - let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); - let _data = await I_STRProxied.getSecurityTokenData.call(_tokenAddress); - assert.equal(_data[0], symbol, "Symbol should match with registered symbol"); - assert.equal(_data[1], token_owner, "Owner should be the deployer of token"); - assert.equal(_data[2], tokenDetails, "Token details should matched with deployed ticker"); - }); - - it("Should alter the old storage", async() => { - await I_STRProxied.changeTheDeployedAddress(symbol, account_temp, {from: account_polymath}); - let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); - assert.equal(_tokenAddress, account_temp, "Should match with the changed address"); - }); - }) - - describe("Transfer the ownership of the proxy contract", async() => { - - it("Should change the ownership of the contract -- because of bad owner", async()=> { - - await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); - }); - - it("Should change the ownership of the contract -- new address should not be 0x", async()=> { - - await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); - }); - - it("Should change the ownership of the contract", async()=> { - await I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_polymath}); - let _currentOwner = await I_SecurityTokenRegistryProxy.proxyOwner.call({from: account_polymath_new}); - assert.equal(_currentOwner, account_polymath_new, "Should equal to the new owner"); - }); - - it("Should change the implementation contract and version by the new owner", async() => { - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath}); - await I_SecurityTokenRegistryProxy.upgradeTo("1.2.0", I_SecurityTokenRegistry.address, {from: account_polymath_new}); - let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.2.0", "Version mis-match"); - assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address, "Implemnted address is not matched"); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - }); - }) - - -}) + it('Should change the implementation contract and version by the new owner', async () => { + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + await I_SecurityTokenRegistryProxy.upgradeTo('1.2.0', I_SecurityTokenRegistry.address, { from: account_polymath_new }); + let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, '') + .replace(/\n/, ''), + '1.2.0', + 'Version mis-match' + ); + assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address, 'Implemnted address is not matched'); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + }); + }); +}); diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index 67e6a57a0..7674b6e5c 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -2,118 +2,114 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); -const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); +const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); +const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); +const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); -const MockModuleRegistry = artifacts.require("./MockModuleRegistry.sol"); +const MockModuleRegistry = artifacts.require('./MockModuleRegistry.sol'); const OwnedUpgradeabilityProxy = artifacts.require('./OwnedUpgradeabilityProxy.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol') -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const STFactory = artifacts.require('./STFactory.sol'); const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol') +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract ("ModuleRegistryProxy", accounts => { - - - let I_SecurityTokenRegistry; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManagerfactory; - let I_MockModuleRegistry; - let I_STFactory; - let I_PolymathRegistry; - let I_ModuleRegistryProxy; - let I_PolyToken; - let I_STRProxied; - let I_MRProxied; - let I_SecurityToken; - let I_ModuleRegistry; - let I_FeatureRegistry; - - let account_polymath; - let account_temp; - let token_owner; - let account_polymath_new; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - const version = "1.0.0"; - const message = "Transaction Should Fail!"; - - // SecurityToken Details for funds raise Type ETH - const name = "Team"; - const symbol = "SAP"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - - const transferManagerKey = 2; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - async function readStorage(contractAddress, slot) { - return await web3.eth.getStorageAt(contractAddress, slot); - } - - before(async() => { - account_polymath = accounts[0]; - account_temp = accounts[1]; - token_owner = accounts[2]; - account_polymath_new = accounts[3]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // Printing all the contract addresses - console.log(` +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port + +contract('ModuleRegistryProxy', accounts => { + let I_SecurityTokenRegistry; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManagerfactory; + let I_MockModuleRegistry; + let I_STFactory; + let I_PolymathRegistry; + let I_ModuleRegistryProxy; + let I_PolyToken; + let I_STRProxied; + let I_MRProxied; + let I_SecurityToken; + let I_ModuleRegistry; + let I_FeatureRegistry; + + let account_polymath; + let account_temp; + let token_owner; + let account_polymath_new; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + const version = '1.0.0'; + const message = 'Transaction Should Fail!'; + + // SecurityToken Details for funds raise Type ETH + const name = 'Team'; + const symbol = 'SAP'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + + const transferManagerKey = 2; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + async function readStorage(contractAddress, slot) { + return await web3.eth.getStorageAt(contractAddress, slot); + } + + before(async () => { + account_polymath = accounts[0]; + account_temp = accounts[1]; + token_owner = accounts[2]; + account_polymath_new = accounts[3]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // Step 4: Deploy the SecurityTokenRegistry + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); + + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -124,161 +120,167 @@ contract ("ModuleRegistryProxy", accounts => { GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Attach the implementation address', async () => { + // Storage + // __version -- index 11 + // __implementation -- index 12 + // __upgradeabilityOwner -- index 13 + + it('Should attach the MR implementation and version', async () => { + let bytesProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesProxy, { from: account_polymath }); + let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); + assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, '') + .replace(/\n/, ''), + '1.0.0' + ); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); }); - describe("Attach the implementation address", async() => { - - // Storage - // __version -- index 11 - // __implementation -- index 12 - // __upgradeabilityOwner -- index 13 - - it("Should attach the MR implementation and version", async() => { - let bytesProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, {from: account_polymath}); - let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.0.0"); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - }); - - it("Deploy the essential smart contracts", async() => { - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + it('Deploy the essential smart contracts', async () => { + // STEP 4: Deploy the GeneralTransferManagerFactory + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - // Step 3: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - }) + // Register the Modules with the ModuleRegistry contract - it("Verify the initialize data", async() => { - assert.equal((await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("owner"))), account_polymath, "Should equal to right address"); - assert.equal((await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry"))), I_PolymathRegistry.address); - }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - }) + // Step 3: Deploy the STFactory contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - describe("Feed some data in storage", async() => { + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + }); - it("Register and verify the new module", async() => { + it('Verify the initialize data', async () => { + assert.equal( + await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')), + account_polymath, + 'Should equal to right address' + ); + assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('polymathRegistry')), I_PolymathRegistry.address); + }); + }); + + describe('Feed some data in storage', async () => { + it('Register and verify the new module', async () => { + I_GeneralPermissionManagerfactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + + assert.notEqual( + I_GeneralPermissionManagerfactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralPermissionManagerFactory contract was not deployed' + ); + + await I_MRProxied.registerModule(I_GeneralPermissionManagerfactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerfactory.address, true, { from: account_polymath }); + }); + }); - I_GeneralPermissionManagerfactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + describe('Upgrade the imlplementation address', async () => { + it('Should upgrade the version and implementation address -- fail bad owner', async () => { + I_MockModuleRegistry = await MockModuleRegistry.new({ from: account_polymath }); + await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', I_MockModuleRegistry.address, { from: account_temp })); + }); - assert.notEqual( - I_GeneralPermissionManagerfactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralPermissionManagerFactory contract was not deployed" - ); + it('Should upgrade the version and implementation address -- Implementaion address should be a contract address', async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', account_temp, { from: account_polymath })); + }); - await I_MRProxied.registerModule(I_GeneralPermissionManagerfactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerfactory.address, true, { from: account_polymath }); + it('Should upgrade the version and implementation address -- Implemenation address should not be 0x', async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', '0x00000000000000000000000000000000000000', { from: account_polymath })); + }); - }); + it('Should upgrade the version and implementation address -- Implemenation address should not be the same address', async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', I_ModuleRegistry.address, { from: account_polymath })); + }); - }) + it('Should upgrade the version and implementation address -- same version as previous is not allowed', async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.0.0', I_MockModuleRegistry.address, { from: account_polymath })); + }); - describe("Upgrade the imlplementation address", async() => { + it('Should upgrade the version and implementation address -- empty version string is not allowed', async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo('', I_MockModuleRegistry.address, { from: account_polymath })); + }); - it("Should upgrade the version and implementation address -- fail bad owner", async() => { - - I_MockModuleRegistry = await MockModuleRegistry.new({from: account_polymath}); - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_temp})); - }); + it('Should upgrade the version and the implementation address successfully', async () => { + await I_ModuleRegistryProxy.upgradeTo('1.1.0', I_MockModuleRegistry.address, { from: account_polymath }); + let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, '') + .replace(/\n/, ''), + '1.1.0', + 'Version mis-match' + ); + assert.equal(await readStorage(c.address, 12), I_MockModuleRegistry.address, 'Implemnted address is not matched'); + I_MRProxied = await MockModuleRegistry.at(I_ModuleRegistryProxy.address); + }); + }); - it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); - }); + describe('Execute functionality of the implementation contract on the earlier storage', async () => { + it('Should get the previous data', async () => { + let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); + assert.equal(_data.length, 0, 'Should give the original length'); + }); - it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); - }); + it('Should alter the old storage', async () => { + await I_MRProxied.addMoreReputation(I_GeneralTransferManagerFactory.address, [account_polymath, account_temp], { + from: account_polymath + }); + let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); + assert.equal(_data.length, 2, 'Should give the updated length'); + }); + }); - it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_ModuleRegistry.address, {from: account_polymath})); - }); + describe('Transfer the ownership of the proxy contract', async () => { + it('Should change the ownership of the contract -- because of bad owner', async () => { + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_temp })); + }); - it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.0.0", I_MockModuleRegistry.address, {from: account_polymath})); - }); + it('Should change the ownership of the contract -- new address should not be 0x', async () => { + await catchRevert( + I_ModuleRegistryProxy.transferProxyOwnership('0x00000000000000000000000000000000000000', { from: account_polymath }) + ); + }); - it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("", I_MockModuleRegistry.address, {from: account_polymath})); - }); - - it("Should upgrade the version and the implementation address successfully", async() => { - await I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_polymath}); - let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.1.0", "Version mis-match"); - assert.equal(await readStorage(c.address, 12), I_MockModuleRegistry.address, "Implemnted address is not matched"); - I_MRProxied = await MockModuleRegistry.at(I_ModuleRegistryProxy.address); - }); + it('Should change the ownership of the contract', async () => { + await I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_polymath }); + let _currentOwner = await I_ModuleRegistryProxy.proxyOwner.call({ from: account_polymath_new }); + assert.equal(_currentOwner, account_polymath_new, 'Should equal to the new owner'); }); - describe("Execute functionality of the implementation contract on the earlier storage", async() => { - - it("Should get the previous data", async() => { - let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); - assert.equal(_data.length, 0, "Should give the original length"); - }); - - it("Should alter the old storage", async() => { - await I_MRProxied.addMoreReputation(I_GeneralTransferManagerFactory.address, [account_polymath, account_temp], {from: account_polymath}); - let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); - assert.equal(_data.length, 2, "Should give the updated length"); - }); - }) - - describe("Transfer the ownership of the proxy contract", async() => { - - it("Should change the ownership of the contract -- because of bad owner", async()=> { - - await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); - }); - - it("Should change the ownership of the contract -- new address should not be 0x", async()=> { - - await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); - }); - - it("Should change the ownership of the contract", async()=> { - await I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_polymath}); - let _currentOwner = await I_ModuleRegistryProxy.proxyOwner.call({from: account_polymath_new}); - assert.equal(_currentOwner, account_polymath_new, "Should equal to the new owner"); - }); - - it("Should change the implementation contract and version by the new owner", async() => { - I_ModuleRegistry = await ModuleRegistry.new({from: account_polymath}); - await I_ModuleRegistryProxy.upgradeTo("1.2.0", I_ModuleRegistry.address, {from: account_polymath_new}); - let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.2.0", "Version mis-match"); - assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address, "Implemnted address is not matched"); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - }); - }) - - -}) + it('Should change the implementation contract and version by the new owner', async () => { + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + await I_ModuleRegistryProxy.upgradeTo('1.2.0', I_ModuleRegistry.address, { from: account_polymath_new }); + let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, '') + .replace(/\n/, ''), + '1.2.0', + 'Version mis-match' + ); + assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address, 'Implemnted address is not matched'); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + }); + }); +}); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 1615a5ce1..4b8380424 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -22,183 +22,182 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port contract('TrackedRedemption', accounts => { + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_temp; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = 'Transaction Should Fail!'; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_TrackedRedemptionFactory; + let I_GeneralPermissionManager; + let I_TrackedRedemption; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_MRProxied; + let I_PolymathRegistry; + + // SecurityToken Details + const name = 'Team'; + const symbol = 'sap'; + const tokenDetails = 'This is equity type of issuance'; + const decimals = 18; + const contact = 'team@polymath.network'; + let snapId; + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const checkpointKey = 4; + const burnKey = 5; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei('250'); + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_TrackedRedemptionFactory; - let I_GeneralPermissionManager; - let I_TrackedRedemption; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_MRProxied; - let I_PolymathRegistry; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - let snapId; - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - const burnKey = 5; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + // STEP 3: Deploy the ModuleRegistry - // STEP 5: Deploy the GeneralDelegateManagerFactory + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + // STEP 4: Deploy the GeneralTransferManagerFactory - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - // STEP 4: Deploy the TrackedRedemption - I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_TrackedRedemptionFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "TrackedRedemptionFactory contract was not deployed" - ); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralTransferManagerFactory contract was not deployed' + ); + + // STEP 5: Deploy the GeneralDelegateManagerFactory + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - // Step 6: Deploy the STFactory contract + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'GeneralDelegateManagerFactory contract was not deployed' + ); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + // STEP 4: Deploy the TrackedRedemption + I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_TrackedRedemptionFactory.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'TrackedRedemptionFactory contract was not deployed' + ); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + // Step 6: Deploy the STFactory contract - // Step 7: Deploy the SecurityTokenRegistry contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + // Step 7: Deploy the SecurityTokenRegistry contract - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + '0x0000000000000000000000000000000000000000', + 'SecurityTokenRegistry contract was not deployed' + ); - // STEP 5: Register the Modules with the ModuleRegistry contract + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // STEP 5: Register the Modules with the ModuleRegistry contract - // (C) : Register the TrackedRedemptionFactory - await I_MRProxied.registerModule(I_TrackedRedemptionFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_TrackedRedemptionFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the TrackedRedemptionFactory + await I_MRProxied.registerModule(I_TrackedRedemptionFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_TrackedRedemptionFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -214,161 +213,144 @@ contract('TrackedRedemption', accounts => { TrackedRedemptionFactory: ${I_TrackedRedemptionFactory.address} ----------------------------------------------------------------------------- `); + }); + + describe('Generate the SecurityToken', async () => { + it('Should register the ticker before the generation of the security token', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - }); - - it("Should successfully attach the TrackedRedemption with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, "", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "TrackedRedemption", - "TrackedRedemption module was not added" - ); - I_TrackedRedemption = TrackedRedemption.at(tx.logs[2].args._module); - }); + it('Should generate the new security token with the same symbol as registered above', async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + }); + + it('Should intialize the auto attached modules', async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it('Should successfully attach the TrackedRedemption with the security token', async () => { + const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, '', 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), + 'TrackedRedemption', + 'TrackedRedemption module was not added' + ); + I_TrackedRedemption = TrackedRedemption.at(tx.logs[2].args._module); }); + }); + + describe('Make Redemptions', async () => { + it('Buy some tokens for account_investor1 (1 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Jump time + await increaseTime(5000); - describe("Make Redemptions", async() => { - - it("Buy some tokens for account_investor1 (1 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); - }); - - it("Buy some tokens for account_investor2 (2 ETH)", async() => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); - }); - - it("Redeem some tokens - fail insufficient allowance", async() => { - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - - - await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1})); - }); - - it("Redeem some tokens", async() => { - await I_SecurityToken.approve(I_TrackedRedemption.address, web3.utils.toWei('1', 'ether'), {from: account_investor1}); - let tx = await I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1}); - console.log(JSON.stringify(tx.logs)); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Mismatch address"); - assert.equal(tx.logs[0].args._value, web3.utils.toWei('1', 'ether'), "Wrong value"); - }); - - it("Get the init data", async() => { - let tx = await I_TrackedRedemption.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); - }); - - it("Should get the listed permissions", async() => { - let tx = await I_TrackedRedemption.getPermissions.call(); - assert.equal(tx.length,0); - }); - - describe("Test cases for the TrackedRedemptionFactory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_TrackedRedemptionFactory.getType.call(), 5); - assert.equal(await I_TrackedRedemptionFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()) - .replace(/\u0000/g, ''), - "TrackedRedemption", - "Wrong Module added"); - assert.equal(await I_TrackedRedemptionFactory.getDescription.call(), - "Track token redemptions", - "Wrong Module added"); - assert.equal(await I_TrackedRedemptionFactory.getTitle.call(), - "Tracked Redemption", - "Wrong Module added"); - assert.equal(await I_TrackedRedemptionFactory.getInstructions.call(), - "Allows an investor to redeem security tokens which are tracked by this module", - "Wrong Module added"); - let tags = await I_TrackedRedemptionFactory.getTags.call(); - assert.equal(tags.length, 2); - - }); - }); + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); }); + it('Buy some tokens for account_investor2 (2 ETH)', async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); + }); + + it('Redeem some tokens - fail insufficient allowance', async () => { + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); + + await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + }); + + it('Redeem some tokens', async () => { + await I_SecurityToken.approve(I_TrackedRedemption.address, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + let tx = await I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + console.log(JSON.stringify(tx.logs)); + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Mismatch address'); + assert.equal(tx.logs[0].args._value, web3.utils.toWei('1', 'ether'), 'Wrong value'); + }); + + it('Get the init data', async () => { + let tx = await I_TrackedRedemption.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); + }); + + it('Should get the listed permissions', async () => { + let tx = await I_TrackedRedemption.getPermissions.call(); + assert.equal(tx.length, 0); + }); + + describe('Test cases for the TrackedRedemptionFactory', async () => { + it('should get the exact details of the factory', async () => { + assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); + assert.equal(await I_TrackedRedemptionFactory.getType.call(), 5); + assert.equal(await I_TrackedRedemptionFactory.getVersion.call(), '1.0.0'); + assert.equal( + web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()).replace(/\u0000/g, ''), + 'TrackedRedemption', + 'Wrong Module added' + ); + assert.equal(await I_TrackedRedemptionFactory.getDescription.call(), 'Track token redemptions', 'Wrong Module added'); + assert.equal(await I_TrackedRedemptionFactory.getTitle.call(), 'Tracked Redemption', 'Wrong Module added'); + assert.equal( + await I_TrackedRedemptionFactory.getInstructions.call(), + 'Allows an investor to redeem security tokens which are tracked by this module', + 'Wrong Module added' + ); + let tags = await I_TrackedRedemptionFactory.getTags.call(); + assert.equal(tags.length, 2); + }); + }); + }); }); From 87ea437b2596eb366a9c53d54d90dda560cfc7c3 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 09:02:34 +0530 Subject: [PATCH 059/142] Revert "added prettier" This reverts commit 4e037d6983bb0be041c8dcfff13f053632e33f7a. Will execute prettier after conflict resolution --- package.json | 4 +- test/a_poly_oracle.js | 530 +-- test/b_capped_sto.js | 1724 ++++---- test/c_checkpoints.js | 543 +-- test/d_count_transfer_manager.js | 646 +-- test/e_erc20_dividends.js | 1671 ++++--- test/f_ether_dividends.js | 1633 ++++--- test/g_general_permission_manager.js | 663 ++- test/h_general_transfer_manager.js | 1312 +++--- test/helpers/createInstances.js | 218 +- test/helpers/encodeCall.js | 9 +- test/helpers/exceptions.js | 16 +- test/helpers/latestTime.js | 7 +- test/helpers/signData.js | 20 +- test/helpers/testprivateKey.js | 6 +- test/helpers/time.js | 112 +- test/helpers/utils.js | 99 +- test/i_Issuance.js | 643 +-- test/j_manual_approval_transfer_manager.js | 1147 +++-- test/k_module_registry.js | 961 ++-- test/l_percentage_transfer_manager.js | 675 ++- test/m_presale_sto.js | 729 +-- test/n_security_token_registry.js | 2030 +++++---- test/o_security_token.js | 1991 +++++---- test/p_usd_tiered_sto.js | 4654 ++++++++------------ test/q_usd_tiered_sto_sim.js | 1536 +++---- test/r_concurrent_STO.js | 569 +-- test/s_v130_to_v140_upgrade.js | 925 ++-- test/t_security_token_registry_proxy.js | 506 ++- test/u_module_registry_proxy.js | 480 +- test/v_tracked_redemptions.js | 596 +-- 31 files changed, 12925 insertions(+), 13730 deletions(-) diff --git a/package.json b/package.json index f7105ee09..3e06d880f 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,7 @@ "flatten-oracles": "sol-merger './contracts/oracles/*.sol' ./flat/oracles", "flatten": "sol-merger './contracts/*.sol' ./flat", "ethereum-bridge": "node_modules/.bin/ethereum-bridge -H localhost:8545 -a 9 --dev", - "st20generator": "node demo/ST20Generator", - "pretty": "prettier --write --single-quote --print-width 140 --tab-width 2 \"**/*.js\"" + "st20generator": "node demo/ST20Generator" }, "repository": { "type": "git", @@ -72,7 +71,6 @@ "devDependencies": { "@soldoc/soldoc": "^0.4.3", "eslint": "^4.19.1", - "prettier": "^1.14.3", "eslint-config-standard": "^11.0.0", "eslint-plugin-import": "^2.10.0", "eslint-plugin-node": "^6.0.1", diff --git a/test/a_poly_oracle.js b/test/a_poly_oracle.js index dcbe8d563..da8268238 100644 --- a/test/a_poly_oracle.js +++ b/test/a_poly_oracle.js @@ -1,267 +1,283 @@ const PolyOracle = artifacts.require('./MockPolyOracle.sol'); import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { increaseTime } from './helpers/time'; +import {increaseTime} from './helpers/time'; import { catchRevert } from './helpers/exceptions'; const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port - -contract('PolyOracle', accounts => { - let I_PolyOracle; - let owner; - const URL = - '[URL] json(https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?id=2496&convert=USD&CMC_PRO_API_KEY=${[decrypt] BBObnGOy63qVI3OR2+MX88dzSMVjQboiZc7Wluuh2ngkSgiX1csxWgbAFtu22jbrry42zwCS4IUmer1Wk+1o1XhF7hyspoGCkbufQqYwuUYwcA2slX6RbEDai7NgdkgNGWSwd6DcuN8jD5ZMTkX68rJKkplr}).data."2496".quote.USD.price'; - const alternateURL = 'json(https://min-api.cryptocompare.com/data/price?fsym=POLY&tsyms=USD).USD'; - const SanityBounds = 20 * 10 ** 16; - const GasLimit = 100000; - const TimeTolerance = 5 * 60; - const message = 'Txn should fail'; - let latestPrice; - let requestIds = new Array(); - - before(async () => { - owner = accounts[0]; - I_PolyOracle = await PolyOracle.new({ from: owner }); - }); - - describe('state variables checks', async () => { - it('should set and check the api url', async () => { - await I_PolyOracle.setOracleURL(URL, { from: owner }); - let url = await I_PolyOracle.oracleURL.call(); - assert.equal(URL, url); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract('PolyOracle', accounts=> { + +let I_PolyOracle; +let owner; +const URL = '[URL] json(https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?id=2496&convert=USD&CMC_PRO_API_KEY=${[decrypt] BBObnGOy63qVI3OR2+MX88dzSMVjQboiZc7Wluuh2ngkSgiX1csxWgbAFtu22jbrry42zwCS4IUmer1Wk+1o1XhF7hyspoGCkbufQqYwuUYwcA2slX6RbEDai7NgdkgNGWSwd6DcuN8jD5ZMTkX68rJKkplr}).data."2496".quote.USD.price'; +const alternateURL = "json(https://min-api.cryptocompare.com/data/price?fsym=POLY&tsyms=USD).USD"; +const SanityBounds = 20*10**16; +const GasLimit = 100000; +const TimeTolerance = 5*60; +const message = "Txn should fail"; +let latestPrice; +let requestIds = new Array(); + + before(async()=> { + owner = accounts[0]; + I_PolyOracle = await PolyOracle.new({from : owner}); }); - it('should check the sanity bounds', async () => { - let sanityBounds = await I_PolyOracle.sanityBounds.call(); - assert.equal(SanityBounds, sanityBounds); - }); - - it('should check the gas limits', async () => { - let gasLimit = await I_PolyOracle.gasLimit.call(); - assert.equal(GasLimit, gasLimit); - }); - - it('should check the oraclize time tolerance', async () => { - let timeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); - assert.equal(TimeTolerance, timeTolerance); - }); - }); - - describe('Scheduling test cases', async () => { - it('Should schedule the timing of the call - fails - non owner', async () => { - let timeScheduling = [latestTime() + duration.minutes(1), latestTime() + duration.minutes(2), latestTime() + duration.minutes(3)]; - await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: accounts[1], value: web3.utils.toWei('2') })); - }); - - it('Should schedule the timing of the call - fails - no value', async () => { - let timeScheduling = [latestTime() + duration.minutes(1), latestTime() + duration.minutes(2), latestTime() + duration.minutes(3)]; - await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner })); - }); - - it('Should schedule the timing of the call - single call', async () => { - let blockNo = latestBlock(); - let tx = await I_PolyOracle.schedulePriceUpdatesFixed([], { from: owner, value: web3.utils.toWei('1') }); - assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); - // await increaseTime(50); - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); - // const log = await logNewPriceWatcher; - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.'); - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.'); - assert.equal(logNewPriceWatcher.args._oldPrice.toNumber(), 0); - console.log( - 'Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY' - ); - }); - - it('Should schedule the timing of the call - multiple calls', async () => { - let blockNo = latestBlock(); - let timeScheduling = [latestTime() + duration.seconds(10), latestTime() + duration.seconds(20)]; - let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner, value: web3.utils.toWei('1.5') }); - - let event_data = tx.logs; - - for (var i = 0; i < event_data.length; i++) { - let time = event_data[i].args._time; - console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); - assert.isAtMost(time.toNumber(), timeScheduling[i]); - } - - // Wait for the callback to be invoked by oraclize and the event to be emitted - const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - const log = await logNewPriceWatcher; - assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.'); - assert.isNotNull(log.args._price, 'Price returned was null.'); - console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); - }); - - it('Should schedule to call using iters - fails', async () => { - await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, { from: accounts[6] })); - }); - - it('Should schedule to call using iters', async () => { - let blockNo = latestBlock(); - console.log(`Latest Block number of the local chain:${blockNo}`); - let tx = await I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 10, 2, { from: owner }); - let event_data = tx.logs; - for (var i = 0; i < event_data.length; i++) { - let time = event_data[i].args._time; - requestIds.push(event_data[i].args._queryId); - console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); - assert.isAtMost(time.toNumber(), latestTime() + (i + 1) * 30); - } - // Wait for the callback to be invoked by oraclize and the event to be emitted - const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - const log = await logNewPriceWatcher; - assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.'); - assert.isNotNull(log.args._price, 'Price returned was null.'); - console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); - latestPrice = log.args._price; - }); - }); - - describe('Ownable functions', async () => { - it('Should change the Poly USD price manually - fail - bad account', async () => { - await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), { from: accounts[5] })); - }); - - it('Should change the Poly USD price manually', async () => { - await I_PolyOracle.setPOLYUSD(latestPrice.add(1), { from: owner }); - let price2 = await I_PolyOracle.getPriceAndTime.call(); - assert.equal(price2[0].toNumber(), latestPrice.add(1).toNumber()); - }); - - it('Should freeze the Oracle manually', async () => { - await catchRevert(I_PolyOracle.setFreezeOracle(true, { from: accounts[5] })); - }); - - it('Should change the URL manually', async () => { - let freeze_ = await I_PolyOracle.freezeOracle.call(); - await I_PolyOracle.setFreezeOracle(true, { from: owner }); - let freeze = await I_PolyOracle.freezeOracle.call(); - assert.isFalse(freeze_); - assert.isTrue(freeze); - await I_PolyOracle.setFreezeOracle(false, { from: owner }); - }); - - it('Should change the sanity bounds manually - fails - bad owner', async () => { - await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), { from: accounts[6] })); - }); - - it('Should change the sanity bounds manually', async () => { - console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); - await I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), { from: owner }); - let sanityBounds = await I_PolyOracle.sanityBounds.call(); - console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); - assert.equal(sanityBounds.toNumber(), new BigNumber(25).times(new BigNumber(10).pow(16)).toNumber()); - }); - - it('Should change the gas price manually - fails - bad owner', async () => { - await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)), { from: accounts[6] })); - }); - it('Should change the gas price manually', async () => { - await I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)), { from: owner }); - let blockNo = latestBlock(); - let timeScheduling = [latestTime() + duration.seconds(10), latestTime() + duration.seconds(20)]; - let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner, value: web3.utils.toWei('2') }); - - let event_data = tx.logs; - - for (var i = 0; i < event_data.length; i++) { - let time = event_data[i].args._time; - console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); - assert.isAtMost(time.toNumber(), timeScheduling[i]); - } - - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.'); - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.'); - console.log( - 'Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY' - ); - // assert.isTrue(false); - }); - - it('Should change the gas limit manually - fails', async () => { - await catchRevert(I_PolyOracle.setGasLimit(50000, { from: accounts[6] })); - }); - - it('Should change the gas limit manually', async () => { - await I_PolyOracle.setGasLimit(50000, { from: owner }); - let gasLimit = await I_PolyOracle.gasLimit.call(); - assert.equal(gasLimit.toNumber(), 50000); - await I_PolyOracle.setGasLimit(100000, { from: owner }); - }); - - it('Should blacklist some IDS manually - fails - wrong size', async () => { - let ignore = [true]; - await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, { from: accounts[6] })); - }); - - it('Should blacklist some IDS manually', async () => { - let ignore = [false, true]; - console.log(requestIds); - await I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, { from: owner }); - - // let ignoreRequestId0 = await I_PolyOracle.ignoreRequestIds.call(requestIds[1]); - // assert.equal(ignoreRequestId0,true); - - // let ignoreRequestId1 = await I_PolyOracle.ignoreRequestIds.call(requestIds[2]); - // assert.equal(ignoreRequestId1,false); - }); - - it('Should change the oraclize time tolerance manually - fails', async () => { - await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600, { from: accounts[6] })); - }); - - it('Should change the oraclize time tolerance manually', async () => { - await I_PolyOracle.setOraclizeTimeTolerance(3600, { from: owner }); - let oraclizeTimeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); - assert.equal(oraclizeTimeTolerance.toNumber(), 3600); - }); - - it('should change the api URL manually', async () => { - await catchRevert(I_PolyOracle.setOracleURL(alternateURL, { from: accounts[6] })); - }); - - it('should change the api URL manually', async () => { - await I_PolyOracle.setOracleURL(alternateURL, { from: owner }); - await I_PolyOracle.setOracleQueryType('URL', { from: owner }); - let url = await I_PolyOracle.oracleURL.call(); - assert.equal(alternateURL, url); - }); - - it('Should schedule the timing of the call - after changes', async () => { - let blockNo = latestBlock(); - let tx = await I_PolyOracle.schedulePriceUpdatesFixed([], { from: owner, value: web3.utils.toWei('1') }); - assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); - const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.'); - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.'); - console.log( - 'Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY' - ); - // assert.isTrue(false); - }); - }); - - describe('Get Functions call', async () => { - it('Should get the currency address', async () => { - let polyTokenAddress = await I_PolyOracle.getCurrencyAddress.call(); - assert.equal(polyTokenAddress, '0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC'.toLowerCase()); - }); - - it('Should get the currency symbol', async () => { - let currency = await I_PolyOracle.getCurrencySymbol.call(); - assert.equal(web3.utils.toAscii(currency).replace(/\u0000/g, ''), 'POLY'); - }); - - it('Should get the currency denomination', async () => { - let denomination = await I_PolyOracle.getCurrencyDenominated.call(); - assert.equal(web3.utils.toAscii(denomination).replace(/\u0000/g, ''), 'USD'); - }); - }); -}); + describe("state variables checks", async() => { + + it("should set and check the api url", async() => { + await I_PolyOracle.setOracleURL(URL, {from: owner}); + let url = await I_PolyOracle.oracleURL.call(); + assert.equal(URL, url); + }); + + it("should check the sanity bounds", async() => { + let sanityBounds = await I_PolyOracle.sanityBounds.call(); + assert.equal(SanityBounds, sanityBounds); + }); + + it("should check the gas limits", async() => { + let gasLimit = await I_PolyOracle.gasLimit.call(); + assert.equal(GasLimit, gasLimit); + }); + + it("should check the oraclize time tolerance", async() => { + let timeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); + assert.equal(TimeTolerance, timeTolerance); + }); + + }) + + describe("Scheduling test cases", async() => { + + it("Should schedule the timing of the call - fails - non owner", async() => { + + let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: accounts[1], value: web3.utils.toWei("2")})); + }); + + it("Should schedule the timing of the call - fails - no value", async() => { + + let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner})); + }) + + it("Should schedule the timing of the call - single call", async() => { + let blockNo = latestBlock(); + let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); + assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); + // await increaseTime(50); + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); + // const log = await logNewPriceWatcher; + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') + assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') + assert.equal(logNewPriceWatcher.args._oldPrice.toNumber(), 0); + console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') + + }); + + it("Should schedule the timing of the call - multiple calls", async() => { + let blockNo = latestBlock(); + let timeScheduling = [latestTime()+duration.seconds(10), latestTime()+duration.seconds(20)] + let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner, value:web3.utils.toWei("1.5")}); + + let event_data = tx.logs; + + for (var i = 0; i < event_data.length; i++) { + let time = event_data[i].args._time; + console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); + assert.isAtMost(time.toNumber(), timeScheduling[i]); + } + + // Wait for the callback to be invoked by oraclize and the event to be emitted + const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); + const log = await logNewPriceWatcher; + assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') + assert.isNotNull(log.args._price, 'Price returned was null.'); + console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') + }); + + it("Should schedule to call using iters - fails", async() => { + + await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, {from: accounts[6]})); + }) + + it("Should schedule to call using iters", async() => { + let blockNo = latestBlock(); + console.log(`Latest Block number of the local chain:${blockNo}`); + let tx = await I_PolyOracle.schedulePriceUpdatesRolling(latestTime()+10, 10, 2, {from: owner}); + let event_data = tx.logs; + for (var i = 0; i < event_data.length; i++) { + let time = event_data[i].args._time; + requestIds.push(event_data[i].args._queryId); + console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); + assert.isAtMost(time.toNumber(), latestTime() + ((i + 1) * 30)); + } + // Wait for the callback to be invoked by oraclize and the event to be emitted + const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); + const log = await logNewPriceWatcher; + assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') + assert.isNotNull(log.args._price, 'Price returned was null.') + console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + latestPrice = log.args._price; + }); + }) + + describe("Ownable functions", async() => { + + it("Should change the Poly USD price manually - fail - bad account", async() => { + + await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: accounts[5]})); + }); + + it("Should change the Poly USD price manually", async() => { + await I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: owner}); + let price2 = await I_PolyOracle.getPriceAndTime.call(); + assert.equal(price2[0].toNumber(), latestPrice.add(1).toNumber()); + }) + + it("Should freeze the Oracle manually", async() => { + + await catchRevert(I_PolyOracle.setFreezeOracle(true, {from: accounts[5]})); + }) + + it("Should change the URL manually", async() => { + let freeze_ = await I_PolyOracle.freezeOracle.call(); + await I_PolyOracle.setFreezeOracle(true, {from: owner}); + let freeze = await I_PolyOracle.freezeOracle.call(); + assert.isFalse(freeze_); + assert.isTrue(freeze); + await I_PolyOracle.setFreezeOracle(false, {from: owner}); + }) + + it("Should change the sanity bounds manually - fails - bad owner", async() => { + + await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : accounts[6]})); + }) + + it("Should change the sanity bounds manually", async() => { + console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); + await I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : owner}); + let sanityBounds = await I_PolyOracle.sanityBounds.call(); + console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); + assert.equal(sanityBounds.toNumber(), new BigNumber(25).times(new BigNumber(10).pow(16)).toNumber()) + }); + + it("Should change the gas price manually - fails - bad owner", async() => { + + await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : accounts[6]})); + }); + + it("Should change the gas price manually", async() => { + await I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : owner}); + let blockNo = latestBlock(); + let timeScheduling = [latestTime()+duration.seconds(10), latestTime()+duration.seconds(20)]; + let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner, value:web3.utils.toWei("2")}); + + let event_data = tx.logs; + + for (var i = 0; i < event_data.length; i++) { + let time = event_data[i].args._time; + console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); + assert.isAtMost(time.toNumber(), timeScheduling[i]); + } + + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); + + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') + assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') + console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + // assert.isTrue(false); + + }); + + it("Should change the gas limit manually - fails", async() => { + + await catchRevert(I_PolyOracle.setGasLimit(50000,{from : accounts[6]})); + }); + + it("Should change the gas limit manually", async() => { + await I_PolyOracle.setGasLimit(50000,{from : owner}); + let gasLimit = await I_PolyOracle.gasLimit.call(); + assert.equal(gasLimit.toNumber(),50000); + await I_PolyOracle.setGasLimit(100000,{from : owner}); + }); + + it("Should blacklist some IDS manually - fails - wrong size", async() => { + + let ignore = [true]; + await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds,ignore,{from : accounts[6]})); + }); + + it("Should blacklist some IDS manually", async() => { + let ignore = [false, true]; + console.log(requestIds); + await I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, {from : owner}); + + // let ignoreRequestId0 = await I_PolyOracle.ignoreRequestIds.call(requestIds[1]); + // assert.equal(ignoreRequestId0,true); + + // let ignoreRequestId1 = await I_PolyOracle.ignoreRequestIds.call(requestIds[2]); + // assert.equal(ignoreRequestId1,false); + + }); + + it("Should change the oraclize time tolerance manually - fails", async() => { + + await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600,{from : accounts[6]})); + }) + + it("Should change the oraclize time tolerance manually", async() => { + await I_PolyOracle.setOraclizeTimeTolerance(3600,{from : owner}); + let oraclizeTimeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); + assert.equal(oraclizeTimeTolerance.toNumber(),3600); + }); + + it("should change the api URL manually", async() => { + + await catchRevert(I_PolyOracle.setOracleURL(alternateURL, {from: accounts[6]})); + }) + + it("should change the api URL manually", async() => { + await I_PolyOracle.setOracleURL(alternateURL, {from: owner}); + await I_PolyOracle.setOracleQueryType("URL", {from: owner}); + let url = await I_PolyOracle.oracleURL.call(); + assert.equal(alternateURL, url); + }); + + it("Should schedule the timing of the call - after changes", async() => { + let blockNo = latestBlock(); + let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); + assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); + const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); + assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') + assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') + console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + // assert.isTrue(false); + }); + + }) + + describe("Get Functions call", async() => { + it("Should get the currency address", async() => { + let polyTokenAddress = await I_PolyOracle.getCurrencyAddress.call(); + assert.equal(polyTokenAddress, ("0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC").toLowerCase()); + }); + + it("Should get the currency symbol", async() => { + let currency = await I_PolyOracle.getCurrencySymbol.call(); + assert.equal(web3.utils.toAscii(currency).replace(/\u0000/g, ''), "POLY"); + }); + + it("Should get the currency denomination", async() => { + let denomination = await I_PolyOracle.getCurrencyDenominated.call(); + assert.equal(web3.utils.toAscii(denomination).replace(/\u0000/g, ''), "USD"); + }) + + }) + +}) diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 0554ddf0f..6bc815bdc 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -14,152 +14,143 @@ const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager') const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port let ETH = 0; let POLY = 1; let DAI = 2; contract('CappedSTO', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_investor3; - let account_fundsReceiver; - - let balanceOfReceiver; - let message = 'Transaction Should Fail!'; - // investor Details - let fromTime; - let toTime; - let expiryTime; - let P_fromTime; - let P_toTime; - let P_expiryTime; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_SecurityTokenRegistry; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_FeatureRegistry; - let I_CappedSTOFactory; - let I_STFactory; - let I_SecurityToken_ETH; - let I_SecurityToken_POLY; - let I_CappedSTO_Array_ETH = []; - let I_CappedSTO_Array_POLY = []; - let I_PolyToken; - let I_PolymathRegistry; - let I_STRProxied; - let I_MRProxied; - let pauseTime; - - // SecurityToken Details for funds raise Type ETH - const name = 'Team'; - const symbol = 'SAP'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - // SecurityToken Details for funds raise Type POLY - const P_name = 'Team Poly'; - const P_symbol = 'PAS'; - const P_tokenDetails = 'This is equity type of issuance'; - const P_decimals = 18; - - // Module key - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // Capped STO details - let startTime_ETH1; - let endTime_ETH1; - let startTime_ETH2; - let endTime_ETH2; - const cap = web3.utils.toWei('10000'); - const rate = 1000; - const E_fundRaiseType = 0; - - let startTime_POLY1; - let endTime_POLY1; - let startTime_POLY2; - let endTime_POLY2; - let blockNo; - const P_cap = web3.utils.toWei('50000'); - const P_fundRaiseType = 1; - const P_rate = 5; - const cappedSTOSetupCost = web3.utils.toWei('20000', 'ether'); - const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[4]; - account_investor2 = accounts[3]; - account_investor3 = accounts[5]; - account_fundsReceiver = accounts[2]; - token_owner = account_issuer; - - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [ - I_PolymathRegistry, - I_PolyToken, - I_FeatureRegistry, - I_ModuleRegistry, - I_ModuleRegistryProxy, - I_MRProxied, - I_GeneralTransferManagerFactory, - I_STFactory, - I_SecurityTokenRegistry, - I_SecurityTokenRegistryProxy, - I_STRProxied - ] = instances; - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // STEP 6: Deploy the CappedSTOFactory - - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CappedSTOFactory contract was not deployed' - ); - - // STEP 7: Register the Modules with the ModuleRegistry contract - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_investor3; + let account_fundsReceiver; + + let balanceOfReceiver; + let message = "Transaction Should Fail!"; + // investor Details + let fromTime; + let toTime; + let expiryTime; + let P_fromTime; + let P_toTime; + let P_expiryTime; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_SecurityTokenRegistry; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_FeatureRegistry; + let I_CappedSTOFactory; + let I_STFactory; + let I_SecurityToken_ETH; + let I_SecurityToken_POLY; + let I_CappedSTO_Array_ETH = []; + let I_CappedSTO_Array_POLY = []; + let I_PolyToken; + let I_PolymathRegistry; + let I_STRProxied; + let I_MRProxied; + let pauseTime; + + // SecurityToken Details for funds raise Type ETH + const name = "Team"; + const symbol = "SAP"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + + // SecurityToken Details for funds raise Type POLY + const P_name = "Team Poly"; + const P_symbol = "PAS"; + const P_tokenDetails = "This is equity type of issuance"; + const P_decimals = 18; + + // Module key + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // Capped STO details + let startTime_ETH1; + let endTime_ETH1; + let startTime_ETH2; + let endTime_ETH2; + const cap = web3.utils.toWei("10000"); + const rate = 1000; + const E_fundRaiseType = 0; + + let startTime_POLY1; + let endTime_POLY1; + let startTime_POLY2; + let endTime_POLY2; + let blockNo; + const P_cap = web3.utils.toWei("50000"); + const P_fundRaiseType = 1; + const P_rate = 5; + const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); + const maxCost = cappedSTOSetupCost; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[4]; + account_investor2 = accounts[3]; + account_investor3 = accounts[5] + account_fundsReceiver = accounts[2]; + token_owner = account_issuer; + + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + + // STEP 5: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 6: Deploy the CappedSTOFactory + + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); + + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); + + + // STEP 7: Register the Modules with the ModuleRegistry contract + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -175,748 +166,909 @@ contract('CappedSTO', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol); }); - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + describe("Generate the SecurityToken", async() => { - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol); + }); - I_SecurityToken_ETH = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - const log = await promisifyLogWatch(I_SecurityToken_ETH.ModuleAdded({ from: _blockNo }), 1); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); - }); + I_SecurityToken_ETH = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken_ETH.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - it('Should mint the tokens before attaching the STO', async () => { - await catchRevert( - I_SecurityToken_ETH.mint('0x0000000000000000000000000000000000000000', web3.utils.toWei('1'), { from: token_owner }) - ); - }); + const log = await promisifyLogWatch(I_SecurityToken_ETH.ModuleAdded({from: _blockNo}), 1); - it("Should fail to launch the STO due to security token doesn't have the sufficient POLY", async () => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken_ETH.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + it("Should mint the tokens before attaching the STO", async() => { + + await catchRevert(I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), {from: token_owner})); + }); - it('Should fail to launch the STO due to rate is 0', async () => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner }); + it("Should fail to launch the STO due to security token doesn't have the sufficient POLY", async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); + + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + it("Should fail to launch the STO due to rate is 0", async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner}); - it('Should fail to launch the STO due to startTime > endTime', async () => { - let bytesSTO = encodeModuleCall(STOParameters, [ - Math.floor(Date.now() / 1000 + 100000), - Math.floor(Date.now() / 1000 + 1000), - cap, - rate, - [E_fundRaiseType], - account_fundsReceiver - ]); - - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); + + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - it('Should fail to launch the STO due to cap is of 0 securityToken', async () => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); + it("Should fail to launch the STO due to startTime > endTime", async () => { + let bytesSTO = encodeModuleCall(STOParameters, [ Math.floor(Date.now()/1000 + 100000), Math.floor(Date.now()/1000 + 1000), cap, rate, [E_fundRaiseType], account_fundsReceiver]); + + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); + it("Should fail to launch the STO due to cap is of 0 securityToken", async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [ startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); + + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); - it('Should successfully attach the STO module to the security token', async () => { - startTime_ETH1 = latestTime() + duration.days(1); - endTime_ETH1 = startTime_ETH1 + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver]); - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + it("Should successfully attach the STO module to the security token", async () => { + startTime_ETH1 = latestTime() + duration.days(1); + endTime_ETH1 = startTime_ETH1 + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); - I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); - }); - }); - - describe('verify the data of STO', async () => { - it('Should verify the configuration of the STO', async () => { - assert.equal(await I_CappedSTO_Array_ETH[0].startTime.call(), startTime_ETH1, "STO Configuration doesn't set as expected"); - assert.equal(await I_CappedSTO_Array_ETH[0].endTime.call(), endTime_ETH1, "STO Configuration doesn't set as expected"); - assert.equal((await I_CappedSTO_Array_ETH[0].cap.call()).toNumber(), cap, "STO Configuration doesn't set as expected"); - assert.equal(await I_CappedSTO_Array_ETH[0].rate.call(), rate, "STO Configuration doesn't set as expected"); - assert.equal(await I_CappedSTO_Array_ETH[0].fundRaiseTypes.call(E_fundRaiseType), true, "STO Configuration doesn't set as expected"); - }); - }); - - describe('Buy tokens', async () => { - it('Should buy the tokens -- failed due to startTime is greater than Current time', async () => { - await catchRevert( - web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('1', 'ether') - }) - ); + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); + }); }); - it('Should buy the tokens -- failed due to invested amount is zero', async () => { - await catchRevert( - web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0', 'ether') - }) - ); + describe("verify the data of STO", async () => { + + it("Should verify the configuration of the STO", async() => { + assert.equal( + await I_CappedSTO_Array_ETH[0].startTime.call(), + startTime_ETH1, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_ETH[0].endTime.call(), + endTime_ETH1, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_ETH[0].cap.call()).toNumber(), + cap, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_ETH[0].rate.call(), + rate, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_ETH[0].fundRaiseTypes.call(E_fundRaiseType), + true, + "STO Configuration doesn't set as expected" + ); + }); }); - it('Should buy the tokens -- Failed due to investor is not in the whitelist', async () => { - await catchRevert( - web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('1', 'ether') - }) - ); - }); + describe("Buy tokens", async() => { - it('Should buy the tokens -- Failed due to wrong granularity', async () => { - await catchRevert( - web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0.1111', 'ether') - }) - ); - }); + it("Should buy the tokens -- failed due to startTime is greater than Current time", async () => { + + await catchRevert(web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('1', 'ether') + })); + }); - it('Should Buy the tokens', async () => { - blockNo = latestBlock(); - fromTime = latestTime(); - toTime = latestTime() + duration.days(15); - expiryTime = toTime + duration.days(100); - P_fromTime = fromTime + duration.days(1); - P_toTime = P_fromTime + duration.days(50); - P_expiryTime = toTime + duration.days(100); + it("Should buy the tokens -- failed due to invested amount is zero", async () => { + + await catchRevert(web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('0', 'ether') + })); + }); - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - // Add the Investor in to the whitelist + it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { + + await catchRevert(web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('1', 'ether') + })); + }); - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { - from: account_issuer, - gas: 500000 - }); + it("Should buy the tokens -- Failed due to wrong granularity", async () => { + + await catchRevert(web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('0.1111', 'ether') + })); + }); - assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); + it("Should Buy the tokens", async() => { + blockNo = latestBlock(); + fromTime = latestTime(); + toTime = latestTime() + duration.days(15); + expiryTime = toTime + duration.days(100); + P_fromTime = fromTime + duration.days(1); + P_toTime = P_fromTime + duration.days(50); + P_expiryTime = toTime + duration.days(100); + + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + fromTime, + toTime, + expiryTime, + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(duration.days(1)); + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }); + + assert.equal( + (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1 + ); + + assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 1); + + assert.equal( + (await I_SecurityToken_ETH.balanceOf(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + }); - // Jump time - await increaseTime(duration.days(1)); - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); + it("Verification of the event Token Purchase", async() => { + const log = await promisifyLogWatch(I_CappedSTO_Array_ETH[0].TokenPurchase({from: blockNo}), 1); + + assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); + assert.equal( + (log.args.amount) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000, + "Wrong No. token get dilivered" + ); + }); - assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); + it("Should pause the STO -- Failed due to wrong msg.sender", async()=> { + + await catchRevert(I_CappedSTO_Array_ETH[0].pause({from: account_investor1})); + }); - assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 1); + it("Should pause the STO", async()=> { + pauseTime = latestTime(); + let tx = await I_CappedSTO_Array_ETH[0].pause({from: account_issuer}); + assert.isTrue(await I_CappedSTO_Array_ETH[0].paused.call()); + }); - assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - }); + it("Should fail to buy the tokens after pausing the STO", async() => { + + await catchRevert(web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + })); + }); - it('Verification of the event Token Purchase', async () => { - const log = await promisifyLogWatch(I_CappedSTO_Array_ETH[0].TokenPurchase({ from: blockNo }), 1); + it("Should unpause the STO -- Failed due to wrong msg.sender", async()=> { + + await catchRevert(I_CappedSTO_Array_ETH[0].unpause({from: account_investor1})); + }); - assert.equal(log.args.purchaser, account_investor1, 'Wrong address of the investor'); - assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000, 'Wrong No. token get dilivered'); - }); + it("Should unpause the STO", async()=> { + let tx = await I_CappedSTO_Array_ETH[0].unpause({from: account_issuer}); + assert.isFalse(await I_CappedSTO_Array_ETH[0].paused.call()); + }); - it('Should pause the STO -- Failed due to wrong msg.sender', async () => { - await catchRevert(I_CappedSTO_Array_ETH[0].pause({ from: account_investor1 })); - }); + it("Should buy the tokens -- Failed due to wrong granularity", async () => { + + await catchRevert(web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_ETH[0].address, + value: web3.utils.toWei('0.1111', 'ether') + })); + }); - it('Should pause the STO', async () => { - pauseTime = latestTime(); - let tx = await I_CappedSTO_Array_ETH[0].pause({ from: account_issuer }); - assert.isTrue(await I_CappedSTO_Array_ETH[0].paused.call()); - }); + it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async() => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + fromTime, + toTime + duration.days(20), + expiryTime, + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); + + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor2, + to: I_CappedSTO_Array_ETH[0].address, + gas: 2100000, + value: web3.utils.toWei('9', 'ether') + }); + + assert.equal( + (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 10 + ); + + assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 2); + + assert.equal( + (await I_SecurityToken_ETH.balanceOf(account_investor2)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 9000 + ); + await catchRevert(web3.eth.sendTransaction({ + from: account_investor2, + to: I_CappedSTO_Array_ETH[0].address, + gas: 210000, + value: web3.utils.toWei('1', 'ether') + })); + }); - it('Should fail to buy the tokens after pausing the STO', async () => { - await catchRevert( - web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }) - ); - }); + it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { + const newBalance = await web3.eth.getBalance(account_fundsReceiver); + //console.log("WWWW",newBalance,await I_CappedSTO.fundsRaised.call(),balanceOfReceiver); + let op = (BigNumber(newBalance).minus(balanceOfReceiver)).toNumber(); + assert.equal( + (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).toNumber(), + op, + "Somewhere raised money get stolen or sent to wrong wallet" + ); + }); - it('Should unpause the STO -- Failed due to wrong msg.sender', async () => { - await catchRevert(I_CappedSTO_Array_ETH[0].unpause({ from: account_investor1 })); - }); + it("Should get the raised amount of ether", async() => { + assert.equal(await I_CappedSTO_Array_ETH[0].getRaised.call(ETH), web3.utils.toWei('10','ether')); + }); - it('Should unpause the STO', async () => { - let tx = await I_CappedSTO_Array_ETH[0].unpause({ from: account_issuer }); - assert.isFalse(await I_CappedSTO_Array_ETH[0].paused.call()); - }); + it("Should get the raised amount of poly", async() => { + assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('0','ether')); + }); - it('Should buy the tokens -- Failed due to wrong granularity', async () => { - await catchRevert( - web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0.1111', 'ether') - }) - ); }); - it('Should restrict to buy tokens after hiting the cap in second tx first tx pass', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime + duration.days(20), expiryTime, true, { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); - - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO_Array_ETH[0].address, - gas: 2100000, - value: web3.utils.toWei('9', 'ether') - }); - - assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10); - - assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 2); - - assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 9000); - await catchRevert( - web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO_Array_ETH[0].address, - gas: 210000, - value: web3.utils.toWei('1', 'ether') - }) - ); - }); + describe("Reclaim poly sent to STO by mistake", async() => { - it('Should fundRaised value equal to the raised value in the funds receiver wallet', async () => { - const newBalance = await web3.eth.getBalance(account_fundsReceiver); - //console.log("WWWW",newBalance,await I_CappedSTO.fundsRaised.call(),balanceOfReceiver); - let op = BigNumber(newBalance) - .minus(balanceOfReceiver) - .toNumber(); - assert.equal( - (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).toNumber(), - op, - 'Somewhere raised money get stolen or sent to wrong wallet' - ); - }); + it("Should fail to reclaim POLY because token contract address is 0 address", async() => { + let value = web3.utils.toWei('100','ether'); + await I_PolyToken.getTokens(value, account_investor1); + await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); - it('Should get the raised amount of ether', async () => { - assert.equal(await I_CappedSTO_Array_ETH[0].getRaised.call(ETH), web3.utils.toWei('10', 'ether')); - }); + + await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); + }); - it('Should get the raised amount of poly', async () => { - assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('0', 'ether')); + it("Should successfully reclaim POLY", async() => { + let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); + let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); + let initContractBalance = await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address); + let value = web3.utils.toWei('100','ether'); + + await I_PolyToken.getTokens(value, account_investor1); + await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); + await I_CappedSTO_Array_ETH[0].reclaimERC20(I_PolyToken.address, { from: token_owner }); + assert.equal((await I_PolyToken.balanceOf(account_investor3)).toNumber(), initInvestorBalance.toNumber(), "tokens are not transfered out from investor account"); + assert.equal((await I_PolyToken.balanceOf(token_owner)).toNumber(), initOwnerBalance.add(value).add(initContractBalance).toNumber(), "tokens are not added to the owner account"); + assert.equal((await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address)).toNumber(), 0, "tokens are not trandfered out from STO contract"); + }); }); - }); - describe('Reclaim poly sent to STO by mistake', async () => { - it('Should fail to reclaim POLY because token contract address is 0 address', async () => { - let value = web3.utils.toWei('100', 'ether'); - await I_PolyToken.getTokens(value, account_investor1); - await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); + describe("Attach second ETH STO module", async() => { - await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); - }); + it("Should successfully attach the second STO module to the security token", async () => { + startTime_ETH2 = latestTime() + duration.days(1); + endTime_ETH2 = startTime_ETH2 + duration.days(30); - it('Should successfully reclaim POLY', async () => { - let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); - let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); - let initContractBalance = await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address); - let value = web3.utils.toWei('100', 'ether'); - - await I_PolyToken.getTokens(value, account_investor1); - await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); - await I_CappedSTO_Array_ETH[0].reclaimERC20(I_PolyToken.address, { from: token_owner }); - assert.equal( - (await I_PolyToken.balanceOf(account_investor3)).toNumber(), - initInvestorBalance.toNumber(), - 'tokens are not transfered out from investor account' - ); - assert.equal( - (await I_PolyToken.balanceOf(token_owner)).toNumber(), - initOwnerBalance - .add(value) - .add(initContractBalance) - .toNumber(), - 'tokens are not added to the owner account' - ); - assert.equal( - (await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address)).toNumber(), - 0, - 'tokens are not trandfered out from STO contract' - ); - }); - }); + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner}); + let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH2, endTime_ETH2, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - describe('Attach second ETH STO module', async () => { - it('Should successfully attach the second STO module to the security token', async () => { - startTime_ETH2 = latestTime() + duration.days(1); - endTime_ETH2 = startTime_ETH2 + duration.days(30); + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); + }); - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH2, endTime_ETH2, cap, rate, [E_fundRaiseType], account_fundsReceiver]); - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + it("Should verify the configuration of the STO", async() => { + assert.equal( + await I_CappedSTO_Array_ETH[1].startTime.call(), + startTime_ETH2, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_ETH[1].endTime.call(), + endTime_ETH2, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_ETH[1].cap.call()).toNumber(), + cap, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_ETH[1].rate.call(), + rate, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_ETH[1].fundRaiseTypes.call(E_fundRaiseType), + true, + "STO Configuration doesn't set as expected" + ); + }); - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); - I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); - }); + it("Should successfully whitelist investor 3", async() => { - it('Should verify the configuration of the STO', async () => { - assert.equal(await I_CappedSTO_Array_ETH[1].startTime.call(), startTime_ETH2, "STO Configuration doesn't set as expected"); - assert.equal(await I_CappedSTO_Array_ETH[1].endTime.call(), endTime_ETH2, "STO Configuration doesn't set as expected"); - assert.equal((await I_CappedSTO_Array_ETH[1].cap.call()).toNumber(), cap, "STO Configuration doesn't set as expected"); - assert.equal(await I_CappedSTO_Array_ETH[1].rate.call(), rate, "STO Configuration doesn't set as expected"); - assert.equal(await I_CappedSTO_Array_ETH[1].fundRaiseTypes.call(E_fundRaiseType), true, "STO Configuration doesn't set as expected"); - }); + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - it('Should successfully whitelist investor 3', async () => { - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + fromTime, + toTime, + expiryTime, + true, + { + from: account_issuer, + gas: 500000 + }); - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { - from: account_issuer, - gas: 500000 - }); + assert.equal(tx.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); - assert.equal(tx.logs[0].args._investor, account_investor3, 'Failed in adding the investor in whitelist'); + // Jump time to beyond STO start + await increaseTime(duration.days(2)); + }); - // Jump time to beyond STO start - await increaseTime(duration.days(2)); - }); + it("Should invest in second STO - fails due to incorrect beneficiary", async() => { - it('Should invest in second STO - fails due to incorrect beneficiary', async () => { - // Buying on behalf of another user should fail + // Buying on behalf of another user should fail + + await catchRevert(I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') })); - await catchRevert( - I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from: account_issuer, value: web3.utils.toWei('1', 'ether') }) - ); - }); + }); - it('Should allow non-matching beneficiary', async () => { - await I_CappedSTO_Array_ETH[1].changeAllowBeneficialInvestments(true, { from: account_issuer }); - let allow = await I_CappedSTO_Array_ETH[1].allowBeneficialInvestments(); - assert.equal(allow, true, 'allowBeneficialInvestments should be true'); - }); + it("Should allow non-matching beneficiary", async() => { + await I_CappedSTO_Array_ETH[1].changeAllowBeneficialInvestments(true, {from: account_issuer}); + let allow = await I_CappedSTO_Array_ETH[1].allowBeneficialInvestments(); + assert.equal(allow, true, "allowBeneficialInvestments should be true"); + }); - it('Should invest in second STO', async () => { - await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from: account_issuer, value: web3.utils.toWei('1', 'ether') }); + it("Should invest in second STO", async() => { - assert.equal((await I_CappedSTO_Array_ETH[1].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); + await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') }); - assert.equal(await I_CappedSTO_Array_ETH[1].investorCount.call(), 1); + assert.equal( + (await I_CappedSTO_Array_ETH[1].getRaised.call(ETH)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1 + ); - assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor3)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - }); - }); - - describe('Test cases for reaching limit number of STO modules', async () => { - it('Should successfully attach 10 STO modules', async () => { - const MAX_MODULES = 10; - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - - await I_PolyToken.getTokens(cappedSTOSetupCost * 19, token_owner); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost * 19, { from: token_owner }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], account_fundsReceiver]); - - for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal(tx.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', `Wrong STO module added at index ${STOIndex}`); - I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); - } - }); + assert.equal(await I_CappedSTO_Array_ETH[1].investorCount.call(), 1); - it('Should successfully invest in all STO modules attached', async () => { - const MAX_MODULES = 10; - await increaseTime(duration.days(2)); - for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { - await I_CappedSTO_Array_ETH[STOIndex].buyTokens(account_investor3, { - from: account_investor3, - value: web3.utils.toWei('1', 'ether') - }); - assert.equal((await I_CappedSTO_Array_ETH[STOIndex].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - assert.equal(await I_CappedSTO_Array_ETH[STOIndex].investorCount.call(), 1); - } - }); - }); - - describe('Test Cases for an STO of fundraise type POLY', async () => { - describe('Launch a new SecurityToken', async () => { - it('POLY: Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, P_symbol, P_name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, P_symbol); - }); - - it('POLY: Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, P_symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken_POLY = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken_POLY.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); - }); - - it('POLY: Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken_POLY.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it('POLY: Should successfully attach the STO module to the security token', async () => { - startTime_POLY1 = latestTime() + duration.days(2); - endTime_POLY1 = startTime_POLY1 + duration.days(30); - - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner }); - - let bytesSTO = encodeModuleCall(STOParameters, [ - startTime_POLY1, - endTime_POLY1, - P_cap, - P_rate, - [P_fundRaiseType], - account_fundsReceiver - ]); - - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); - I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); - }); + assert.equal( + (await I_SecurityToken_ETH.balanceOf(account_investor3)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + }); }); - describe('verify the data of STO', async () => { - it('Should verify the configuration of the STO', async () => { - assert.equal( - (await I_CappedSTO_Array_POLY[0].startTime.call()).toNumber(), - startTime_POLY1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_POLY[0].endTime.call()).toNumber(), - endTime_POLY1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_POLY[0].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), - BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), - "STO Configuration doesn't set as expected" - ); - assert.equal(await I_CappedSTO_Array_POLY[0].rate.call(), P_rate, "STO Configuration doesn't set as expected"); - assert.equal( - await I_CappedSTO_Array_POLY[0].fundRaiseTypes.call(P_fundRaiseType), - true, - "STO Configuration doesn't set as expected" - ); - }); - }); + describe("Test cases for reaching limit number of STO modules", async() => { - describe('Buy tokens', async () => { - it('Should Buy the tokens', async () => { - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_investor1); - blockNo = latestBlock(); - assert.equal( - (await I_PolyToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10000, - 'Tokens are not transfered properly' - ); + it("Should successfully attach 10 STO modules", async () => { + const MAX_MODULES = 10; + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, P_fromTime, P_toTime, P_expiryTime, true, { - from: account_issuer, - gas: 500000 - }); + await I_PolyToken.getTokens(cappedSTOSetupCost*19, token_owner); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost*19, { from: token_owner}); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], account_fundsReceiver]); - assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); + for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); + I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); + } - // Jump time - await increaseTime(duration.days(17)); - - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 }); - - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { - from: account_investor1, - gas: 6000000 }); - assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - - assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 1); - - assert.equal((await I_SecurityToken_POLY.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 5000); - }); - - it('Verification of the event Token Purchase', async () => { - const log = await promisifyLogWatch(I_CappedSTO_Array_POLY[0].TokenPurchase({ from: blockNo }), 1); - - assert.equal(log.args.purchaser, account_investor1, 'Wrong address of the investor'); - assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 5000, 'Wrong No. token get dilivered'); - }); - - it('Should restrict to buy tokens after hiting the cap in second tx first tx pass', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - P_fromTime, - P_toTime + duration.days(20), - P_expiryTime, - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); - - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_investor2); + it("Should successfully invest in all STO modules attached", async () => { + const MAX_MODULES = 10; + await increaseTime(duration.days(2)); + for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { + await I_CappedSTO_Array_ETH[STOIndex].buyTokens(account_investor3, { from : account_investor3, value: web3.utils.toWei('1', 'ether') }); + assert.equal( + (await I_CappedSTO_Array_ETH[STOIndex].getRaised.call(ETH)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1 + ); + assert.equal(await I_CappedSTO_Array_ETH[STOIndex].investorCount.call(), 1); + } + }); + }); - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 9000 * Math.pow(10, 18), { from: account_investor2 }); + describe("Test Cases for an STO of fundraise type POLY", async() => { - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(9000 * Math.pow(10, 18), { from: account_investor2, gas: 6000000 }); + describe("Launch a new SecurityToken", async() => { - assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10000); + it("POLY: Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, P_symbol, P_name, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, P_symbol); + }); - assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); + it("POLY: Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, { from: token_owner }); - assert.equal((await I_SecurityToken_POLY.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 45000); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, P_symbol, "SecurityToken doesn't get deployed"); - await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 })); - }); + I_SecurityToken_POLY = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - it('Should failed at the time of buying the tokens -- Because STO get expired', async () => { - await increaseTime(duration.days(31)); // increased beyond the end time of the STO + const log = await promisifyLogWatch(I_SecurityToken_POLY.ModuleAdded({from: _blockNo}), 1); - await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 })); - }); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + }); - it('Should fundRaised value equal to the raised value in the funds receiver wallet', async () => { - const balanceRaised = await I_PolyToken.balanceOf.call(account_fundsReceiver); - assert.equal( - (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), - balanceRaised, - 'Somewhere raised money get stolen or sent to wrong wallet' - ); - }); - }); + it("POLY: Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken_POLY.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); - describe('Test cases for the CappedSTOFactory', async () => { - it('should get the exact details of the factory', async () => { - assert.equal((await I_CappedSTOFactory.setupCost.call()).toNumber(), cappedSTOSetupCost); - assert.equal(await I_CappedSTOFactory.getType.call(), 3); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), 'CappedSTO', 'Wrong Module added'); - assert.equal( - await I_CappedSTOFactory.getDescription.call(), - 'Use to collects the funds and once the cap is reached then investment will be no longer entertained', - 'Wrong Module added' - ); - assert.equal(await I_CappedSTOFactory.getTitle.call(), 'Capped STO', 'Wrong Module added'); - assert.equal( - await I_CappedSTOFactory.getInstructions.call(), - 'Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)', - 'Wrong Module added' - ); - let tags = await I_CappedSTOFactory.getTags.call(); - assert.equal(web3.utils.hexToString(tags[0]), 'Capped'); - }); - - it('Should fail to change the title -- bad owner', async () => { - await catchRevert(I_CappedSTOFactory.changeTitle('STO Capped', { from: account_investor1 })); - }); - - it('Should fail to change the title -- zero length', async () => { - await catchRevert(I_CappedSTOFactory.changeTitle('', { from: token_owner })); - }); - - it('Should successfully change the title', async () => { - await I_CappedSTOFactory.changeTitle('STO Capped', { from: token_owner }); - assert.equal(await I_CappedSTOFactory.getTitle.call(), 'STO Capped', "Title doesn't get changed"); - }); - - it('Should fail to change the description -- bad owner', async () => { - await catchRevert(I_CappedSTOFactory.changeDescription('It is only a STO', { from: account_investor1 })); - }); - - it('Should fail to change the description -- zero length', async () => { - await catchRevert(I_CappedSTOFactory.changeDescription('', { from: token_owner })); - }); - - it('Should successfully change the description', async () => { - await I_CappedSTOFactory.changeDescription('It is only a STO', { from: token_owner }); - assert.equal(await I_CappedSTOFactory.getDescription.call(), 'It is only a STO', "Description doesn't get changed"); - }); - - it('Should fail to change the name -- bad owner', async () => { - await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex('STOCapped'), { from: account_investor1 })); - }); - - it('Should fail to change the name -- zero length', async () => { - await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(''), { from: token_owner })); - }); - - it('Should successfully change the name', async () => { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex('STOCapped'), { from: token_owner }); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), 'STOCapped', "Name doesn't get changed"); - }); - - it('Should successfully change the name', async () => { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex('CappedSTO'), { from: token_owner }); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), 'CappedSTO', "Name doesn't get changed"); - }); - }); + it("POLY: Should successfully attach the STO module to the security token", async () => { + startTime_POLY1 = latestTime() + duration.days(2); + endTime_POLY1 = startTime_POLY1 + duration.days(30); - describe('Test cases for the get functions of the capped sto', async () => { - it('Should verify the cap reached or not', async () => { - assert.isTrue(await I_CappedSTO_Array_POLY[0].capReached.call()); - }); + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner}); - it('Should get the raised amount of ether', async () => { - assert.equal(await I_CappedSTO_Array_POLY[0].getRaised.call(ETH), web3.utils.toWei('0', 'ether')); - }); + let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY1, endTime_POLY1, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); - it('Should get the raised amount of poly', async () => { - assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('10000', 'ether')); - }); + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - it('Should get the investors', async () => { - assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); - }); + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); + }); - it('Should get the listed permissions', async () => { - let tx = await I_CappedSTO_Array_POLY[0].getPermissions.call(); - assert.equal(tx.length, 0); - }); + }); - it('Should get the metrics of the STO', async () => { - let metrics = await I_CappedSTO_Array_POLY[0].getSTODetails.call(); - assert.isTrue(metrics[7]); - }); - }); - }); - - describe('Attach second POLY STO module', async () => { - it('Should successfully attach a second STO to the security token', async () => { - startTime_POLY2 = latestTime() + duration.days(1); - endTime_POLY2 = startTime_POLY2 + duration.days(30); - - await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner }); - - let bytesSTO = encodeModuleCall(STOParameters, [ - startTime_POLY2, - endTime_POLY2, - P_cap, - P_rate, - [P_fundRaiseType], - account_fundsReceiver - ]); - - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); - I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); - }); + describe("verify the data of STO", async () => { + + it("Should verify the configuration of the STO", async() => { + assert.equal( + (await I_CappedSTO_Array_POLY[0].startTime.call()).toNumber(), + startTime_POLY1, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_POLY[0].endTime.call()).toNumber(), + endTime_POLY1, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_POLY[0].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), + BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_POLY[0].rate.call(), + P_rate, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_POLY[0].fundRaiseTypes.call(P_fundRaiseType), + true, + "STO Configuration doesn't set as expected" + ); + }); + }); - it('Should verify the configuration of the STO', async () => { - assert.equal( - (await I_CappedSTO_Array_POLY[1].startTime.call()).toNumber(), - startTime_POLY2, - "STO Configuration doesn't set as expected" - ); - assert.equal((await I_CappedSTO_Array_POLY[1].endTime.call()).toNumber(), endTime_POLY2, "STO Configuration doesn't set as expected"); - assert.equal( - (await I_CappedSTO_Array_POLY[1].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), - BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), - "STO Configuration doesn't set as expected" - ); - assert.equal(await I_CappedSTO_Array_POLY[1].rate.call(), P_rate, "STO Configuration doesn't set as expected"); - assert.equal(await I_CappedSTO_Array_POLY[1].fundRaiseTypes.call(P_fundRaiseType), true, "STO Configuration doesn't set as expected"); + describe("Buy tokens", async() => { + + it("Should Buy the tokens", async() => { + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_investor1); + blockNo = latestBlock(); + assert.equal( + (await I_PolyToken.balanceOf(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 10000, + "Tokens are not transfered properly" + ); + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + P_fromTime, + P_toTime, + P_expiryTime, + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(duration.days(17)); + + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}); + + // buyTokensWithPoly transaction + await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( + (1000 * Math.pow(10, 18)), + { + from : account_investor1, + gas: 6000000 + } + ); + + assert.equal( + (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + + assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 1); + + assert.equal( + (await I_SecurityToken_POLY.balanceOf(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 5000 + ); + }); + + it("Verification of the event Token Purchase", async() => { + const log = await promisifyLogWatch(I_CappedSTO_Array_POLY[0].TokenPurchase({from: blockNo}), 1); + + assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); + assert.equal( + (log.args.amount) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 5000, + "Wrong No. token get dilivered" + ); + }); + + it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async() => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + P_fromTime, + P_toTime + duration.days(20), + P_expiryTime, + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); + + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_investor2); + + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (9000 * Math.pow(10, 18)), { from: account_investor2}); + + // buyTokensWithPoly transaction + await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( + (9000 * Math.pow(10, 18)), + {from : account_investor2, gas: 6000000 } + ); + + assert.equal( + (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 10000 + ); + + assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); + + assert.equal( + (await I_SecurityToken_POLY.balanceOf(account_investor2)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 45000 + ); + + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); + }); + + it("Should failed at the time of buying the tokens -- Because STO get expired", async() => { + await increaseTime(duration.days(31)); // increased beyond the end time of the STO + + await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); + }); + + it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { + const balanceRaised = await I_PolyToken.balanceOf.call(account_fundsReceiver); + assert.equal( + (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), + balanceRaised, + "Somewhere raised money get stolen or sent to wrong wallet" + ); + }); + + }); + + describe("Test cases for the CappedSTOFactory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal((await I_CappedSTOFactory.setupCost.call()).toNumber(), cappedSTOSetupCost); + assert.equal(await I_CappedSTOFactory.getType.call(),3); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), + "CappedSTO", + "Wrong Module added"); + assert.equal(await I_CappedSTOFactory.getDescription.call(), + "Use to collects the funds and once the cap is reached then investment will be no longer entertained", + "Wrong Module added"); + assert.equal(await I_CappedSTOFactory.getTitle.call(), + "Capped STO", + "Wrong Module added"); + assert.equal(await I_CappedSTOFactory.getInstructions.call(), + "Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)", + "Wrong Module added"); + let tags = await I_CappedSTOFactory.getTags.call(); + assert.equal(web3.utils.hexToString(tags[0]),"Capped"); + + }); + + it("Should fail to change the title -- bad owner", async() => { + + await catchRevert(I_CappedSTOFactory.changeTitle("STO Capped", {from:account_investor1})); + }); + + it("Should fail to change the title -- zero length", async() => { + + await catchRevert(I_CappedSTOFactory.changeTitle("", {from: token_owner})); + }); + + it("Should successfully change the title", async() => { + await I_CappedSTOFactory.changeTitle("STO Capped", {from: token_owner}); + assert.equal(await I_CappedSTOFactory.getTitle.call(), + "STO Capped", + "Title doesn't get changed"); + }); + + it("Should fail to change the description -- bad owner", async() => { + + await catchRevert(I_CappedSTOFactory.changeDescription("It is only a STO", {from:account_investor1})); + }); + + it("Should fail to change the description -- zero length", async() => { + + await catchRevert(I_CappedSTOFactory.changeDescription("", {from: token_owner})); + }); + + it("Should successfully change the description", async() => { + await I_CappedSTOFactory.changeDescription("It is only a STO", {from: token_owner}); + assert.equal(await I_CappedSTOFactory.getDescription.call(), + "It is only a STO", + "Description doesn't get changed"); + }); + + it("Should fail to change the name -- bad owner", async() => { + + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from:account_investor1})); + }); + + it("Should fail to change the name -- zero length", async() => { + + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(""), {from: token_owner})); + }); + + it("Should successfully change the name", async() => { + await I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from: token_owner}); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), + "STOCapped", + "Name doesn't get changed"); + }); + + it("Should successfully change the name", async() => { + await I_CappedSTOFactory.changeName(web3.utils.stringToHex("CappedSTO"), {from: token_owner}); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), + "CappedSTO", + "Name doesn't get changed"); + }); + + }); + + describe("Test cases for the get functions of the capped sto", async() => { + it("Should verify the cap reached or not", async() => { + assert.isTrue(await I_CappedSTO_Array_POLY[0].capReached.call()); + }); + + it("Should get the raised amount of ether", async() => { + assert.equal(await I_CappedSTO_Array_POLY[0].getRaised.call(ETH), web3.utils.toWei('0','ether')); + }); + + it("Should get the raised amount of poly", async() => { + assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('10000','ether')); + }); + + it("Should get the investors", async() => { + assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(),2); + }); + + it("Should get the listed permissions", async() => { + let tx = await I_CappedSTO_Array_POLY[0].getPermissions.call(); + assert.equal(tx.length,0); + }); + + it("Should get the metrics of the STO", async() => { + let metrics = await I_CappedSTO_Array_POLY[0].getSTODetails.call(); + assert.isTrue(metrics[7]); + }); + + }); }); - it('Should successfully invest in second STO', async () => { - const polyToInvest = 1000; - const stToReceive = polyToInvest * P_rate; - - await I_PolyToken.getTokens(polyToInvest * Math.pow(10, 18), account_investor3); - - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, P_fromTime, P_toTime, P_expiryTime, true, { - from: account_issuer, - gas: 500000 - }); + describe("Attach second POLY STO module", async() => { + it("Should successfully attach a second STO to the security token", async () => { + startTime_POLY2 = latestTime() + duration.days(1); + endTime_POLY2 = startTime_POLY2 + duration.days(30); - // Jump time to beyond STO start - await increaseTime(duration.days(2)); + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner}); - await I_PolyToken.approve(I_CappedSTO_Array_POLY[1].address, polyToInvest * Math.pow(10, 18), { from: account_investor3 }); + let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY2, endTime_POLY2, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); - // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[1].buyTokensWithPoly(polyToInvest * Math.pow(10, 18), { - from: account_investor3, - gas: 6000000 - }); + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); - assert.equal((await I_CappedSTO_Array_POLY[1].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), polyToInvest); + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); + }); - assert.equal(await I_CappedSTO_Array_POLY[1].investorCount.call(), 1); + it("Should verify the configuration of the STO", async() => { + assert.equal( + (await I_CappedSTO_Array_POLY[1].startTime.call()).toNumber(), + startTime_POLY2, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_POLY[1].endTime.call()).toNumber(), + endTime_POLY2, + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_CappedSTO_Array_POLY[1].cap.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), + BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_POLY[1].rate.call(), + P_rate, + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_CappedSTO_Array_POLY[1].fundRaiseTypes.call(P_fundRaiseType), + true, + "STO Configuration doesn't set as expected" + ); + }); - assert.equal((await I_SecurityToken_POLY.balanceOf(account_investor3)).dividedBy(new BigNumber(10).pow(18)).toNumber(), stToReceive); + it("Should successfully invest in second STO", async() => { + + const polyToInvest = 1000; + const stToReceive = polyToInvest * P_rate; + + await I_PolyToken.getTokens((polyToInvest * Math.pow(10, 18)), account_investor3); + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + P_fromTime, + P_toTime, + P_expiryTime, + true, + { + from: account_issuer, + gas: 500000 + }); + + // Jump time to beyond STO start + await increaseTime(duration.days(2)); + + await I_PolyToken.approve(I_CappedSTO_Array_POLY[1].address, (polyToInvest * Math.pow(10, 18)), { from: account_investor3 }); + + // buyTokensWithPoly transaction + await I_CappedSTO_Array_POLY[1].buyTokensWithPoly( + (polyToInvest * Math.pow(10, 18)), + { + from : account_investor3, + gas: 6000000 + } + ); + + assert.equal( + (await I_CappedSTO_Array_POLY[1].getRaised.call(POLY)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + polyToInvest + ); + + assert.equal(await I_CappedSTO_Array_POLY[1].investorCount.call(), 1); + + assert.equal( + (await I_SecurityToken_POLY.balanceOf(account_investor3)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + stToReceive + ); + }); }); - }); }); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index 26ff736f4..9714e7602 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -8,92 +8,83 @@ const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('Checkpoints', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_STRProxied; - let I_MRProxied; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - - // Step 1: Deploy the genral PM ecosystem - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [ - I_PolymathRegistry, - I_PolyToken, - I_FeatureRegistry, - I_ModuleRegistry, - I_ModuleRegistryProxy, - I_MRProxied, - I_GeneralTransferManagerFactory, - I_STFactory, - I_SecurityTokenRegistry, - I_SecurityTokenRegistryProxy, - I_STRProxied - ] = instances; - - // Printing all the contract addresses - console.log(` + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_STRProxied; + let I_MRProxied; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -106,205 +97,215 @@ contract('Checkpoints', accounts => { GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + describe("Generate the SecurityToken", async() => { - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - }); - - describe('Buy tokens using on-chain whitelist', async () => { - it('Should Buy the tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - false, - { - from: account_issuer, - gas: 6000000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('10', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('10', 'ether')); - }); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - it('Should Buy some more tokens', async () => { - // Add the Investor in to the whitelist + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - false, - { - from: account_issuer, - gas: 6000000 - } - ); + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('10', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('10', 'ether')); }); - it('Add a new token holder', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - false, - { - from: account_issuer, - gas: 6000000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('10', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('10', 'ether')); + describe("Buy tokens using on-chain whitelist", async() => { + + it("Should Buy the tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + false, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('10', 'ether') + ); + }); + + it("Should Buy some more tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + false, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('10', 'ether') + ); + }); + + it("Add a new token holder", async() => { + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + false, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), + web3.utils.toWei('10', 'ether') + ); + }); + + it("Fuzz test balance checkpoints", async() => { + await I_SecurityToken.changeGranularity(1, {from: token_owner}); + let cps = []; + let ts = []; + for (let j = 0; j < 10; j++) { + let balance1 = BigNumber(await I_SecurityToken.balanceOf(account_investor1)); + let balance2 = BigNumber(await I_SecurityToken.balanceOf(account_investor2)); + let balance3 = BigNumber(await I_SecurityToken.balanceOf(account_investor3)); + let totalSupply = BigNumber(await I_SecurityToken.totalSupply()); + cps.push([balance1, balance2, balance3]); + ts.push(totalSupply); + console.log("Checkpoint: " + (j + 1) + " Balances: " + JSON.stringify(cps[cps.length - 1]) + " TotalSupply: " + JSON.stringify(totalSupply)); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + let checkpointTimes = (await I_SecurityToken.getCheckpointTimes()); + assert.equal(checkpointTimes.length, (j + 1)); + console.log("Checkpoint Times: " + checkpointTimes); + let txs = Math.floor(Math.random() * 3); + for (let i = 0; i < txs; i++) { + let sender; + let receiver; + let s = Math.random() * 3; + if (s < 1) { + sender = account_investor1; + } else if (s < 2) { + sender = account_investor2; + } else { + sender = account_investor3; + } + let r = Math.random() * 3; + if (r < 1) { + receiver = account_investor1; + } else if (r < 2) { + receiver = account_investor2; + } else { + receiver = account_investor3; + } + let m = Math.random(); + let amount = BigNumber(await I_SecurityToken.balanceOf(sender)).mul(Math.random().toFixed(10)).toFixed(0); + if (m > 0.8) { + console.log("Sending full balance"); + amount = BigNumber(await I_SecurityToken.balanceOf(sender)); + } + console.log("Sender: " + sender + " Receiver: " + receiver + " Amount: " + JSON.stringify(amount)); + await I_SecurityToken.transfer(receiver, amount, { from: sender }); + } + if (Math.random() > 0.5) { + let n = BigNumber(Math.random().toFixed(10)).mul(10**17).toFixed(0); + let p = Math.random() * 3; + let r = Math.random() * 3; + let minter; + if (r < 1) { + minter = account_investor1; + } else if (r < 2) { + minter = account_investor2; + } else { + minter = account_investor3; + } + console.log("Minting: " + n.toString() + " to: " + minter); + await I_SecurityToken.mint(minter, n, { from: token_owner }); + } + console.log("Checking Interim..."); + for (let k = 0; k < cps.length; k++) { + let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); + let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); + let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); + let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); + let balances = [balance1, balance2, balance3]; + console.log("Checking TotalSupply: " + totalSupply + " is " + ts[k] + " at checkpoint: " + (k + 1)); + assert.isTrue(totalSupply.eq(ts[k])); + console.log("Checking Balances: " + balances + " is " + cps[k] + " at checkpoint: " + (k + 1)); + for (let l = 0; l < cps[k].length; l++) { + // console.log(balances[l].toString(), cps[k][l].toString()); + assert.isTrue(balances[l].eq(cps[k][l])); + } + } + } + console.log("Checking..."); + for (let k = 0; k < cps.length; k++) { + let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); + let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); + let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); + let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); + let balances = [balance1, balance2, balance3]; + console.log("Checking TotalSupply: " + totalSupply + " is " + ts[k] + " at checkpoint: " + (k + 1)); + assert.isTrue(totalSupply.eq(ts[k])); + console.log("Checking Balances: " + balances + " is " + cps[k] + " at checkpoint: " + (k + 1)); + for (let l = 0; l < cps[k].length; l++) { + // console.log(balances[l].toString(), cps[k][l].toString()); + assert.isTrue(balances[l].eq(cps[k][l])); + } + } + + }); }); - it('Fuzz test balance checkpoints', async () => { - await I_SecurityToken.changeGranularity(1, { from: token_owner }); - let cps = []; - let ts = []; - for (let j = 0; j < 10; j++) { - let balance1 = BigNumber(await I_SecurityToken.balanceOf(account_investor1)); - let balance2 = BigNumber(await I_SecurityToken.balanceOf(account_investor2)); - let balance3 = BigNumber(await I_SecurityToken.balanceOf(account_investor3)); - let totalSupply = BigNumber(await I_SecurityToken.totalSupply()); - cps.push([balance1, balance2, balance3]); - ts.push(totalSupply); - console.log( - 'Checkpoint: ' + (j + 1) + ' Balances: ' + JSON.stringify(cps[cps.length - 1]) + ' TotalSupply: ' + JSON.stringify(totalSupply) - ); - await I_SecurityToken.createCheckpoint({ from: token_owner }); - let checkpointTimes = await I_SecurityToken.getCheckpointTimes(); - assert.equal(checkpointTimes.length, j + 1); - console.log('Checkpoint Times: ' + checkpointTimes); - let txs = Math.floor(Math.random() * 3); - for (let i = 0; i < txs; i++) { - let sender; - let receiver; - let s = Math.random() * 3; - if (s < 1) { - sender = account_investor1; - } else if (s < 2) { - sender = account_investor2; - } else { - sender = account_investor3; - } - let r = Math.random() * 3; - if (r < 1) { - receiver = account_investor1; - } else if (r < 2) { - receiver = account_investor2; - } else { - receiver = account_investor3; - } - let m = Math.random(); - let amount = BigNumber(await I_SecurityToken.balanceOf(sender)) - .mul(Math.random().toFixed(10)) - .toFixed(0); - if (m > 0.8) { - console.log('Sending full balance'); - amount = BigNumber(await I_SecurityToken.balanceOf(sender)); - } - console.log('Sender: ' + sender + ' Receiver: ' + receiver + ' Amount: ' + JSON.stringify(amount)); - await I_SecurityToken.transfer(receiver, amount, { from: sender }); - } - if (Math.random() > 0.5) { - let n = BigNumber(Math.random().toFixed(10)) - .mul(10 ** 17) - .toFixed(0); - let p = Math.random() * 3; - let r = Math.random() * 3; - let minter; - if (r < 1) { - minter = account_investor1; - } else if (r < 2) { - minter = account_investor2; - } else { - minter = account_investor3; - } - console.log('Minting: ' + n.toString() + ' to: ' + minter); - await I_SecurityToken.mint(minter, n, { from: token_owner }); - } - console.log('Checking Interim...'); - for (let k = 0; k < cps.length; k++) { - let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); - let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); - let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); - let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); - let balances = [balance1, balance2, balance3]; - console.log('Checking TotalSupply: ' + totalSupply + ' is ' + ts[k] + ' at checkpoint: ' + (k + 1)); - assert.isTrue(totalSupply.eq(ts[k])); - console.log('Checking Balances: ' + balances + ' is ' + cps[k] + ' at checkpoint: ' + (k + 1)); - for (let l = 0; l < cps[k].length; l++) { - // console.log(balances[l].toString(), cps[k][l].toString()); - assert.isTrue(balances[l].eq(cps[k][l])); - } - } - } - console.log('Checking...'); - for (let k = 0; k < cps.length; k++) { - let balance1 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor1, k + 1)); - let balance2 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor2, k + 1)); - let balance3 = BigNumber(await I_SecurityToken.balanceOfAt(account_investor3, k + 1)); - let totalSupply = BigNumber(await I_SecurityToken.totalSupplyAt(k + 1)); - let balances = [balance1, balance2, balance3]; - console.log('Checking TotalSupply: ' + totalSupply + ' is ' + ts[k] + ' at checkpoint: ' + (k + 1)); - assert.isTrue(totalSupply.eq(ts[k])); - console.log('Checking Balances: ' + balances + ' is ' + cps[k] + ' at checkpoint: ' + (k + 1)); - for (let l = 0; l < cps[k].length; l++) { - // console.log(balances[l].toString(), cps[k][l].toString()); - assert.isTrue(balances[l].eq(cps[k][l])); - } - } - }); - }); }); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 339cc9a0c..a4e7aa565 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -12,121 +12,109 @@ const CountTransferManager = artifacts.require('./CountTransferManager'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('CountTransferManager', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - - // Contract Instance Declaration - let I_SecurityTokenRegistryProxy; - let P_CountTransferManagerFactory; - let P_CountTransferManager; - let I_GeneralTransferManagerFactory; - let I_CountTransferManagerFactory; - let I_GeneralPermissionManager; - let I_CountTransferManager; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_MRProxied; - let I_STRProxied; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // CountTransferManager details - const holderCount = 2; // Maximum number of token holders - let bytesSTO = encodeModuleCall(['uint256'], [holderCount]); - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[7]; - account_investor2 = accounts[8]; - account_investor3 = accounts[9]; - - // Step 1: Deploy the genral PM ecosystem - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [ - I_PolymathRegistry, - I_PolyToken, - I_FeatureRegistry, - I_ModuleRegistry, - I_ModuleRegistryProxy, - I_MRProxied, - I_GeneralTransferManagerFactory, - I_STFactory, - I_SecurityTokenRegistry, - I_SecurityTokenRegistryProxy, - I_STRProxied - ] = instances; - - // STEP 2: Deploy the CountTransferManager - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_CountTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CountTransferManagerFactory contract was not deployed' - ); - - // STEP 3: Deploy Paid the CountTransferManager - P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei('500', 'ether'), 0, 0, { - from: account_polymath - }); - assert.notEqual( - P_CountTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CountTransferManagerFactory contract was not deployed' - ); - - // (C) : Register the CountTransferManagerFactory - await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid CountTransferManagerFactory - await I_MRProxied.registerModule(P_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_CountTransferManagerFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_SecurityTokenRegistryProxy; + let P_CountTransferManagerFactory; + let P_CountTransferManager; + let I_GeneralTransferManagerFactory; + let I_CountTransferManagerFactory; + let I_GeneralPermissionManager; + let I_CountTransferManager; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_MRProxied; + let I_STRProxied; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // CountTransferManager details + const holderCount = 2; // Maximum number of token holders + let bytesSTO = encodeModuleCall(['uint256'], [holderCount]); + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[7]; + account_investor2 = accounts[8]; + account_investor3 = accounts[9]; + + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + + // STEP 2: Deploy the CountTransferManager + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_CountTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CountTransferManagerFactory contract was not deployed" + ); + + // STEP 3: Deploy Paid the CountTransferManager + P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); + assert.notEqual( + P_CountTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CountTransferManagerFactory contract was not deployed" + ); + + // (C) : Register the CountTransferManagerFactory + await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the Paid CountTransferManagerFactory + await I_MRProxied.registerModule(P_CountTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_CountTransferManagerFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -140,215 +128,243 @@ contract('CountTransferManager', accounts => { CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + it("Should successfully attach the CountTransferManager factory with the security token", async () => { + + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + await catchRevert(I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + }); + + it("Should successfully attach the CountTransferManager factory with the security token", async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "CountTransferManager", + "CountTransferManagerFactory module was not added" + ); + P_CountTransferManager = CountTransferManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it("Should successfully attach the CountTransferManager with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "CountTransferManager", + "CountTransferManager module was not added" + ); + I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); + }); }); - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it('Should successfully attach the CountTransferManager factory with the security token', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); - await catchRevert( - I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei('500', 'ether'), 0, { - from: token_owner + describe("Buy tokens using on-chain whitelist", async() => { + + it("Should Buy the tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should Buy some more tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Should fail to buy some more tokens (more than 2 holders)", async() => { + // Add the Investor in to the whitelist + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + + + await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner })); + }); + + + it("Should still be able to add to original token holders", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('4', 'ether') + ); + }); + + it("Should still be able to transfer between existing token holders before count change", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Should fail in modifying the holder count", async() => { + + await catchRevert(I_CountTransferManager.changeHolderCount(1, { from: account_investor1 })); }) - ); - }); - - it('Should successfully attach the CountTransferManager factory with the security token', async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); - const tx = await I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei('500', 'ether'), 0, { - from: token_owner - }); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), - 'CountTransferManager', - 'CountTransferManagerFactory module was not added' - ); - P_CountTransferManager = CountTransferManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it('Should successfully attach the CountTransferManager with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'CountTransferManager', - 'CountTransferManager module was not added' - ); - I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); - }); - }); - - describe('Buy tokens using on-chain whitelist', async () => { - it('Should Buy the tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Should Buy some more tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - } - ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + it("Modify holder count to 1", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_CountTransferManager.changeHolderCount(1, { from: token_owner }); + + assert.equal( + (await I_CountTransferManager.maxHolderCount()).toNumber(), + 1 + ); + }); + + it("Should still be able to transfer between existing token holders after count change", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('4', 'ether') + ); + }); + + it("Should not be able to transfer to a new token holder", async() => { + + // await I_CountTransferManager.unpause({from: token_owner}); + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 })); + + }); + + it("Should be able to consolidate balances", async() => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + }); + + it("Should get the permission list", async() => { + let perm = await I_CountTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + }); + + describe("Test cases for the factory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal(await I_CountTransferManagerFactory.setupCost.call(),0); + assert.equal(await I_CountTransferManagerFactory.getType.call(),2); + assert.equal(web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()) + .replace(/\u0000/g, ''), + "CountTransferManager", + "Wrong Module added"); + assert.equal(await I_CountTransferManagerFactory.getDescription.call(), + "Restrict the number of investors", + "Wrong Module added"); + assert.equal(await I_CountTransferManagerFactory.getTitle.call(), + "Count Transfer Manager", + "Wrong Module added"); + assert.equal(await I_CountTransferManagerFactory.getInstructions.call(), + "Allows an issuer to restrict the total number of non-zero token holders", + "Wrong Module added"); + + }); + + it("Should get the tags of the factory", async() => { + let tags = await I_CountTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''),"Count"); + }); + }); - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); - }); - - it('Should fail to buy some more tokens (more than 2 holders)', async () => { - // Add the Investor in to the whitelist - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); - - await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner })); - }); - - it('Should still be able to add to original token holders', async () => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('4', 'ether')); - }); - - it('Should still be able to transfer between existing token holders before count change', async () => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); - }); - - it('Should fail in modifying the holder count', async () => { - await catchRevert(I_CountTransferManager.changeHolderCount(1, { from: account_investor1 })); - }); - - it('Modify holder count to 1', async () => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_CountTransferManager.changeHolderCount(1, { from: token_owner }); - - assert.equal((await I_CountTransferManager.maxHolderCount()).toNumber(), 1); }); - it('Should still be able to transfer between existing token holders after count change', async () => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('4', 'ether')); - }); - - it('Should not be able to transfer to a new token holder', async () => { - // await I_CountTransferManager.unpause({from: token_owner}); - await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 })); - }); - - it('Should be able to consolidate balances', async () => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - }); - - it('Should get the permission list', async () => { - let perm = await I_CountTransferManager.getPermissions.call(); - assert.equal(perm.length, 1); - }); - - describe('Test cases for the factory', async () => { - it('should get the exact details of the factory', async () => { - assert.equal(await I_CountTransferManagerFactory.setupCost.call(), 0); - assert.equal(await I_CountTransferManagerFactory.getType.call(), 2); - assert.equal( - web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()).replace(/\u0000/g, ''), - 'CountTransferManager', - 'Wrong Module added' - ); - assert.equal(await I_CountTransferManagerFactory.getDescription.call(), 'Restrict the number of investors', 'Wrong Module added'); - assert.equal(await I_CountTransferManagerFactory.getTitle.call(), 'Count Transfer Manager', 'Wrong Module added'); - assert.equal( - await I_CountTransferManagerFactory.getInstructions.call(), - 'Allows an issuer to restrict the total number of non-zero token holders', - 'Wrong Module added' - ); - }); - - it('Should get the tags of the factory', async () => { - let tags = await I_CountTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Count'); - }); - }); - }); }); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 2aed7cc68..366268e9e 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -11,128 +11,112 @@ const ERC20DividendCheckpoint = artifacts.require('./ERC20DividendCheckpoint'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('ERC20DividendCheckpoint', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - let dividendName = '0x546573744469766964656e640000000000000000000000000000000000000000'; - - // Contract Instance Declaration - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_ERC20DividendCheckpointFactory; - let P_ERC20DividendCheckpointFactory; - let P_ERC20DividendCheckpoint; - let I_GeneralPermissionManager; - let I_ERC20DividendCheckpoint; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_STRProxied; - let I_MRProxied; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - let snapId; - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - // Step 1: Deploy the genral PM ecosystem - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [ - I_PolymathRegistry, - I_PolyToken, - I_FeatureRegistry, - I_ModuleRegistry, - I_ModuleRegistryProxy, - I_MRProxied, - I_GeneralTransferManagerFactory, - I_STFactory, - I_SecurityTokenRegistry, - I_SecurityTokenRegistryProxy, - I_STRProxied - ] = instances; - - // STEP 6: Deploy the ERC20DividendCheckpoint - P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new( - I_PolyToken.address, - web3.utils.toWei('500', 'ether'), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_ERC20DividendCheckpointFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'ERC20DividendCheckpointFactory contract was not deployed' - ); - - // STEP 7: Deploy the ERC20DividendCheckpoint - I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_ERC20DividendCheckpointFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'ERC20DividendCheckpointFactory contract was not deployed' - ); - - // STEP 8: Register the Modules with the ModuleRegistry contract - - // (A) : Register the ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - - // (B) : Register the Paid ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_temp; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; + + // Contract Instance Declaration + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_ERC20DividendCheckpointFactory; + let P_ERC20DividendCheckpointFactory; + let P_ERC20DividendCheckpoint; + let I_GeneralPermissionManager; + let I_ERC20DividendCheckpoint; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_STRProxied; + let I_MRProxied; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + let snapId; + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const checkpointKey = 4; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; + + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + + // STEP 6: Deploy the ERC20DividendCheckpoint + P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + assert.notEqual( + P_ERC20DividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ERC20DividendCheckpointFactory contract was not deployed" + ); + + // STEP 7: Deploy the ERC20DividendCheckpoint + I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_ERC20DividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ERC20DividendCheckpointFactory contract was not deployed" + ); + + // STEP 8: Register the Modules with the ModuleRegistry contract + + // (A) : Register the ERC20DividendCheckpointFactory + await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + + // (B) : Register the Paid ERC20DividendCheckpointFactory + await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${I_PolymathRegistry.address} SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} @@ -146,767 +130,698 @@ contract('ERC20DividendCheckpoint', accounts => { ERC20DividendCheckpointFactory: ${I_ERC20DividendCheckpointFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it('Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment', async () => { - await catchRevert( - I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { from: token_owner }), - 'tx -> failed because Token is not paid' - ); - }); - - it('Should successfully attach the ERC20DividendCheckpoint with the security token with budget', async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); - const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { - from: token_owner - }); - assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), - 'ERC20DividendCheckpoint', - 'ERC20DividendCheckpoint module was not added' - ); - P_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it('Should successfully attach the ERC20DividendCheckpoint with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, '', 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'ERC20DividendCheckpoint', - 'ERC20DividendCheckpoint module was not added' - ); - I_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[2].args._module); - }); - }); - - describe('Check Dividend payouts', async () => { - it('Buy some tokens for account_investor1 (1 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Buy some tokens for account_investor2 (2 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); - }); - - it('Should fail in creating the dividend - incorrect allowance', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, { - from: token_owner - }), - 'tx -> failed because allowance = 0' - ); - }); - - it('Should fail in creating the dividend - maturity > expiry', async () => { - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), { from: token_owner }); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, { - from: token_owner - }), - 'tx -> failed because maturity > expiry' - ); - }); - - it('Should fail in creating the dividend - now > expiry', async () => { - let maturity = latestTime() - duration.days(2); - let expiry = latestTime() - duration.days(1); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, { - from: token_owner - }), - 'tx -> failed because now > expiry' - ); - }); - - it('Should fail in creating the dividend - bad token', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, { - from: token_owner - }), - 'tx -> failed because token address is 0x' - ); - }); - - it('Should fail in creating the dividend - amount is 0', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, { from: token_owner }), - 'tx -> failed because amount < 0' - ); - }); - - it('Create new dividend of POLY tokens', async () => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - - let tx = await I_ERC20DividendCheckpoint.createDividend( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('1.5', 'ether'), - dividendName, - { from: token_owner } - ); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, 'Dividend should be created at checkpoint 1'); - assert.equal(tx.logs[0].args._name.toString(), dividendName, 'Dividend name incorrect in event'); - }); - - it('Investor 1 transfers his token balance to investor 2', async () => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner }), - 'tx -> failed because dividend index has maturity in future' - ); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails not owner', async () => { - // Increase time by 2 day - await increaseTime(duration.days(2)); - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: account_temp }), - 'tx -> failed because msg.sender is not the owner' - ); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }), - 'tx -> failed because dividend index is greator than the dividend array length' - ); }); - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner, gas: 5000000 }); - let investor1BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('1', 'ether')); - //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); - }); - - it('Buy some tokens for account_temp (1 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - latestTime(), - latestTime(), - latestTime() + duration.days(20), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + it("Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment", async () => { + await catchRevert( + I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }), + "tx -> failed because Token is not paid" + ); + }); + + it("Should successfully attach the ERC20DividendCheckpoint with the security token with budget", async () => { + let snapId = await takeSnapshot() + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "ERC20DividendCheckpoint", + "ERC20DividendCheckpoint module was not added" + ); + P_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "ERC20DividendCheckpoint", + "ERC20DividendCheckpoint module was not added" + ); + I_ERC20DividendCheckpoint = ERC20DividendCheckpoint.at(tx.logs[2].args._module); + }); + }); + + describe("Check Dividend payouts", async() => { + + it("Buy some tokens for account_investor1 (1 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Buy some tokens for account_investor2 (2 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Should fail in creating the dividend - incorrect allowance", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because allowance = 0" + ); + }); + + it("Should fail in creating the dividend - maturity > expiry", async() => { + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because maturity > expiry" + ); + }); + + it("Should fail in creating the dividend - now > expiry", async() => { + let maturity = latestTime() - duration.days(2); + let expiry = latestTime() - duration.days(1); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because now > expiry" + ); + }); + + it("Should fail in creating the dividend - bad token", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), + "tx -> failed because token address is 0x" + ); + }); + + it("Should fail in creating the dividend - amount is 0", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}), + "tx -> failed because amount < 0" + ); + }); + + it("Create new dividend of POLY tokens", async() => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); + assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); + }); + + it("Investor 1 transfers his token balance to investor 2", async() => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), {from: account_investor1}); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}), + "tx -> failed because dividend index has maturity in future" + ); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails not owner", async() => { + // Increase time by 2 day + await increaseTime(duration.days(2)); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}), + "tx -> failed because msg.sender is not the owner" + ); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}), + "tx -> failed because dividend index is greator than the dividend array length" + ); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner, gas: 5000000}); + let investor1BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); + assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('1', 'ether')); + //Check fully claimed + assert.equal((await I_ERC20DividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); + }); + + it("Buy some tokens for account_temp (1 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_temp, + latestTime(), + latestTime(), + latestTime() + duration.days(20), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_temp)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should not allow to create dividend without name", async() => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + await catchRevert( + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}), + "tx -> failed because dividend name is empty" + ); + }); + + it("Create new dividend", async() => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + // transfer approved in above test + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 1"); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry", async() => { + await increaseTime(duration.days(12)); + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}), + "tx -> failed because dividend index has passed its expiry" + ); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoin - fails already reclaimed", async() => { + let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); + assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}), + "tx -> failed because dividend index has already been reclaimed" + ); + }); + + it("Buy some tokens for account_investor3 (7 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), + web3.utils.toWei('7', 'ether') + ); + }); + + it("Should allow to exclude same number of address as EXCLUDED_ADDRESS_LIMIT", async() => { + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber() - 1; + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}); + let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); + assert.equal(excluded[0], account_temp); + }); + + it("Exclude account_temp using global exclusion list", async() => { + await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], {from: token_owner}); + let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); + assert.equal(excluded[0], account_temp); + }); + + it("Should not allow to exclude more address than EXCLUDED_ADDRESS_LIMIT", async() => { + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await catchRevert( + I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}), + "tx -> failed because exclude address more than limit" + ); + }); + + it("Create another new dividend", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), dividendName, {from: token_owner}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 2"); + }); + + it("should investor 3 claims dividend - fail bad index", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + + it("should investor 3 claims dividend", async() => { + console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it("should investor 3 claims dividend - fails already claimed", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}), + "tx -> failed because investor already claimed the dividend" + ); + }); + + it("should issuer pushes remain", async() => { + console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let investorTempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); + let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let investorTempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('3', 'ether')); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + assert.equal(investorTempBalanceAfter2.sub(investorTempBalanceAfter1).toNumber(), 0); + //Check fully claimed + assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('10', 'ether')); + }); + + + it("Delete global exclusion list", async() => { + await I_ERC20DividendCheckpoint.setDefaultExcluded([], {from: token_owner}); + }); + + + it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); + }); + + it("Create another new dividend with explicit checkpoint - fails bad allowance", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); + console.log(JSON.stringify(tx.logs[0].args)); + console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); + await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), + "tx -> failed because allowance is not provided" + ); + }); + + it("Create another new dividend with explicit - fails maturity > expiry", async() => { + console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); + + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), {from: token_owner}); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), + "tx -> failed because maturity > expiry" + ); + }); + + it("Create another new dividend with explicit - fails now > expiry", async() => { + console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); + + let maturity = latestTime() - duration.days(5); + let expiry = latestTime() - duration.days(2); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), + "tx -> failed because now > expiry" + ); + }); + + it("Create another new dividend with explicit - fails bad checkpoint", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}), + "tx -> failed because checkpoint id > current checkpoint" + ); + }); + + it("Set withholding tax of 20% on account_temp and 10% on investor2", async() => { + await I_ERC20DividendCheckpoint.setWithholding([account_temp, account_investor2], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}); + }); + + it("Should not allow mismatching input lengths", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}), + "tx -> failed because mismatching input lengths" + ); + }); + + it("Should not allow withholding greater than limit", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**26)], {from: token_owner}), + "tx -> failed because withholding greater than limit" + ); + await catchRevert( + I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20*10**26), {from: token_owner}), + "" + ); + }); + + it("Should not create dividend with more exclusions than limit", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); + let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await catchRevert( + I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, addresses, dividendName, {from: token_owner}), + "tx -> failed because too many address excluded" + ); + }); + + it("Create another new dividend with explicit checkpoint and exclusion", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + //token transfer approved in above test + let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, [account_investor1], dividendName, {from: token_owner}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 3"); + }); + + it("Should not allow excluded to pull Dividend Payment", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor1, gasPrice: 0}), + "tx -> failed because msg.sender is excluded" + ); + }); + + it("Investor 2 claims dividend, issuer pushes investor 1 - fails not owner", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}), + "tx -> failed because not called by the owner" + ); + }); + + it("Investor 2 claims dividend, issuer pushes investor 1 - fails bad index", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + + it("should not calculate dividend for invalid index", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1), + "tx -> failed because dividend index is not valid" + ); + }); + + it("should calculate dividend before the push dividend payment", async() => { + let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); + let dividendAmount3 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor3); + let dividendAmount_temp = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_temp); + assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei("0", "ether")); + assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei("2", "ether")); + assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei("7", "ether")); + assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei("1", "ether")); + assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei("0", "ether")); + assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("0.2", "ether")); + assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei("0", "ether")); + assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0.2", "ether")); + }); + + it("Investor 2 claims dividend", async() => { + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); + await I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor2, gasPrice: 0}); + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.8', 'ether')); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); + assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); + }); + + it("Should issuer pushes temp investor - investor1 excluded", async() => { + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(3, [account_temp, account_investor1], {from: token_owner}); + let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + let tempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('0.8', 'ether')); + //Check fully claimed + assert.equal((await I_ERC20DividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); + }); + + it("should calculate dividend after the push dividend payment", async() => { + let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); + assert.equal(dividendAmount1[0].toNumber(), 0); + assert.equal(dividendAmount2[0].toNumber(), 0); + }); + + it("Should not allow reclaiming withholding tax with incorrect index", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + + it("Issuer reclaims withholding tax", async() => { + let issuerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); + await I_ERC20DividendCheckpoint.withdrawWithholding(3, {from: token_owner, gasPrice: 0}); + let issuerBalanceAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.4', 'ether')) + }); + + it("Issuer unable to reclaim dividend (expiry not passed)", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner}), + "tx -> failed because expiry is in the future" + ); + }); + + it("Issuer is unable to reclaim invalid dividend", async() => { + await increaseTime(11 * 24 * 60 * 60); + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + + it("Investor 3 unable to pull dividend after expiry", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), + "tx -> failed because expiry is in the past" + ); + }); + + it("Issuer is able to reclaim dividend after expiry", async() => { + let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); + await I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); + let tokenOwnerAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); + assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + + it("Issuer is unable to reclaim already reclaimed dividend", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend are already reclaimed" + ); + }); + + it("Investor 3 unable to pull dividend after reclaiming", async() => { + await catchRevert( + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), + "tx -> failed because expiry is in the past" + ); + }); + + it("Should give the right dividend index", async() => { + let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(3); + assert.equal(index[0], 2); + }); + + it("Should give the right dividend index", async() => { + let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(8); + assert.equal(index.length, 0); + }); + + it("Get the init data", async() => { + let tx = await I_ERC20DividendCheckpoint.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + }); + + it("Should get the listed permissions", async() => { + let tx = await I_ERC20DividendCheckpoint.getPermissions.call(); + assert.equal(tx.length,1); + }); + + describe("Test cases for the ERC20DividendCheckpointFactory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); + assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_ERC20DividendCheckpointFactory.getVersion.call(), "1.0.0"); + assert.equal(web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()) + .replace(/\u0000/g, ''), + "ERC20DividendCheckpoint", + "Wrong Module added"); + assert.equal(await I_ERC20DividendCheckpointFactory.getDescription.call(), + "Create ERC20 dividends for token holders at a specific checkpoint", + "Wrong Module added"); + assert.equal(await I_ERC20DividendCheckpointFactory.getTitle.call(), + "ERC20 Dividend Checkpoint", + "Wrong Module added"); + assert.equal(await I_ERC20DividendCheckpointFactory.getInstructions.call(), + "Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", + "Wrong Module added"); + let tags = await I_ERC20DividendCheckpointFactory.getTags.call(); + assert.equal(tags.length, 3); + + }); + }); - assert.equal((await I_SecurityToken.balanceOf(account_temp)).toNumber(), web3.utils.toWei('1', 'ether')); }); - it('Should not allow to create dividend without name', async () => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), { from: token_owner }); - await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', { - from: token_owner - }), - 'tx -> failed because dividend name is empty' - ); - }); - - it('Create new dividend', async () => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - // transfer approved in above test - let tx = await I_ERC20DividendCheckpoint.createDividend( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('1.5', 'ether'), - dividendName, - { from: token_owner } - ); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, 'Dividend should be created at checkpoint 1'); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry', async () => { - await increaseTime(duration.days(12)); - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, { from: token_owner }), - 'tx -> failed because dividend index has passed its expiry' - ); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoin - fails already reclaimed', async () => { - let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }); - assert.equal(tx.logs[0].args._claimedAmount.toNumber(), web3.utils.toWei('1.5', 'ether')); - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }), - 'tx -> failed because dividend index has already been reclaimed' - ); - }); - - it('Buy some tokens for account_investor3 (7 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it('Should allow to exclude same number of address as EXCLUDED_ADDRESS_LIMIT', async () => { - let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber() - 1; - let addresses = []; - addresses.push(account_temp); - while (limit--) addresses.push(limit); - await I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, { from: token_owner }); - let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); - assert.equal(excluded[0], account_temp); - }); - - it('Exclude account_temp using global exclusion list', async () => { - await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], { from: token_owner }); - let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); - assert.equal(excluded[0], account_temp); - }); - - it('Should not allow to exclude more address than EXCLUDED_ADDRESS_LIMIT', async () => { - let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber(); - let addresses = []; - addresses.push(account_temp); - while (limit--) addresses.push(limit); - await catchRevert( - I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, { from: token_owner }), - 'tx -> failed because exclude address more than limit' - ); - }); - - it('Create another new dividend', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), { from: token_owner }); - let tx = await I_ERC20DividendCheckpoint.createDividend( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('10', 'ether'), - dividendName, - { from: token_owner } - ); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, 'Dividend should be created at checkpoint 2'); - }); - - it('should investor 3 claims dividend - fail bad index', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(5, { from: account_investor3, gasPrice: 0 }), - 'tx -> failed because dividend index is not valid' - ); - }); - - it('should investor 3 claims dividend', async () => { - console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await I_ERC20DividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }); - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it('should investor 3 claims dividend - fails already claimed', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }), - 'tx -> failed because investor already claimed the dividend' - ); - }); - - it('should issuer pushes remain', async () => { - console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let investorTempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); - let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let investorTempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('3', 'ether')); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(investorTempBalanceAfter2.sub(investorTempBalanceAfter1).toNumber(), 0); - //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('10', 'ether')); - }); - - it('Delete global exclusion list', async () => { - await I_ERC20DividendCheckpoint.setDefaultExcluded([], { from: token_owner }); - }); - - it('Investor 2 transfers 1 ETH of his token balance to investor 1', async () => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); - }); - - it('Create another new dividend with explicit checkpoint - fails bad allowance', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - let tx = await I_SecurityToken.createCheckpoint({ from: token_owner }); - console.log(JSON.stringify(tx.logs[0].args)); - console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('20', 'ether'), - 4, - dividendName, - { from: token_owner } - ), - 'tx -> failed because allowance is not provided' - ); - }); - - it('Create another new dividend with explicit - fails maturity > expiry', async () => { - console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), { from: token_owner }); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('20', 'ether'), - 4, - dividendName, - { from: token_owner } - ), - 'tx -> failed because maturity > expiry' - ); - }); - - it('Create another new dividend with explicit - fails now > expiry', async () => { - console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - - let maturity = latestTime() - duration.days(5); - let expiry = latestTime() - duration.days(2); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('20', 'ether'), - 4, - dividendName, - { from: token_owner } - ), - 'tx -> failed because now > expiry' - ); - }); - - it('Create another new dividend with explicit - fails bad checkpoint', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('20', 'ether'), - 5, - dividendName, - { from: token_owner } - ), - 'tx -> failed because checkpoint id > current checkpoint' - ); - }); - - it('Set withholding tax of 20% on account_temp and 10% on investor2', async () => { - await I_ERC20DividendCheckpoint.setWithholding( - [account_temp, account_investor2], - [BigNumber(20 * 10 ** 16), BigNumber(10 * 10 ** 16)], - { from: token_owner } - ); - }); - - it('Should not allow mismatching input lengths', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20 * 10 ** 16), BigNumber(10 * 10 ** 16)], { - from: token_owner - }), - 'tx -> failed because mismatching input lengths' - ); - }); - - it('Should not allow withholding greater than limit', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20 * 10 ** 26)], { from: token_owner }), - 'tx -> failed because withholding greater than limit' - ); - await catchRevert(I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20 * 10 ** 26), { from: token_owner }), ''); - }); - - it('Should not create dividend with more exclusions than limit', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), { from: token_owner }); - let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber(); - let addresses = []; - addresses.push(account_temp); - while (limit--) addresses.push(limit); - await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('10', 'ether'), - 4, - addresses, - dividendName, - { from: token_owner } - ), - 'tx -> failed because too many address excluded' - ); - }); - - it('Create another new dividend with explicit checkpoint and exclusion', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - //token transfer approved in above test - let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( - maturity, - expiry, - I_PolyToken.address, - web3.utils.toWei('10', 'ether'), - 4, - [account_investor1], - dividendName, - { from: token_owner } - ); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, 'Dividend should be created at checkpoint 3'); - }); - - it('Should not allow excluded to pull Dividend Payment', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor1, gasPrice: 0 }), - 'tx -> failed because msg.sender is excluded' - ); - }); - - it('Investor 2 claims dividend, issuer pushes investor 1 - fails not owner', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1], { - from: account_investor2, - gasPrice: 0 - }), - 'tx -> failed because not called by the owner' - ); - }); - - it('Investor 2 claims dividend, issuer pushes investor 1 - fails bad index', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1], { - from: token_owner, - gasPrice: 0 - }), - 'tx -> failed because dividend index is not valid' - ); - }); - - it('should not calculate dividend for invalid index', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1), - 'tx -> failed because dividend index is not valid' - ); - }); - - it('should calculate dividend before the push dividend payment', async () => { - let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); - let dividendAmount3 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor3); - let dividendAmount_temp = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_temp); - assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei('0', 'ether')); - assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei('2', 'ether')); - assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei('7', 'ether')); - assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei('0', 'ether')); - assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei('0.2', 'ether')); - assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei('0', 'ether')); - assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei('0.2', 'ether')); - }); - - it('Investor 2 claims dividend', async () => { - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); - await I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.8', 'ether')); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); - assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); - }); - - it('Should issuer pushes temp investor - investor1 excluded', async () => { - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(3, [account_temp, account_investor1], { from: token_owner }); - let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - let tempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('0.8', 'ether')); - //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); - }); - - it('should calculate dividend after the push dividend payment', async () => { - let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); - assert.equal(dividendAmount1[0].toNumber(), 0); - assert.equal(dividendAmount2[0].toNumber(), 0); - }); - - it('Should not allow reclaiming withholding tax with incorrect index', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.withdrawWithholding(300, { from: token_owner, gasPrice: 0 }), - 'tx -> failed because dividend index is not valid' - ); - }); - - it('Issuer reclaims withholding tax', async () => { - let issuerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); - await I_ERC20DividendCheckpoint.withdrawWithholding(3, { from: token_owner, gasPrice: 0 }); - let issuerBalanceAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.4', 'ether')); - }); - - it('Issuer unable to reclaim dividend (expiry not passed)', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner }), - 'tx -> failed because expiry is in the future' - ); - }); - - it('Issuer is unable to reclaim invalid dividend', async () => { - await increaseTime(11 * 24 * 60 * 60); - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(8, { from: token_owner, gasPrice: 0 }), - 'tx -> failed because dividend index is not valid' - ); - }); - - it('Investor 3 unable to pull dividend after expiry', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 }), - 'tx -> failed because expiry is in the past' - ); - }); - - it('Issuer is able to reclaim dividend after expiry', async () => { - let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); - await I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }); - let tokenOwnerAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); - assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it('Issuer is unable to reclaim already reclaimed dividend', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }), - 'tx -> failed because dividend are already reclaimed' - ); - }); - - it('Investor 3 unable to pull dividend after reclaiming', async () => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 }), - 'tx -> failed because expiry is in the past' - ); - }); - - it('Should give the right dividend index', async () => { - let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(3); - assert.equal(index[0], 2); - }); - - it('Should give the right dividend index', async () => { - let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(8); - assert.equal(index.length, 0); - }); - - it('Get the init data', async () => { - let tx = await I_ERC20DividendCheckpoint.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); - }); - - it('Should get the listed permissions', async () => { - let tx = await I_ERC20DividendCheckpoint.getPermissions.call(); - assert.equal(tx.length, 1); - }); - - describe('Test cases for the ERC20DividendCheckpointFactory', async () => { - it('should get the exact details of the factory', async () => { - assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(), 4); - assert.equal(await I_ERC20DividendCheckpointFactory.getVersion.call(), '1.0.0'); - assert.equal( - web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()).replace(/\u0000/g, ''), - 'ERC20DividendCheckpoint', - 'Wrong Module added' - ); - assert.equal( - await I_ERC20DividendCheckpointFactory.getDescription.call(), - 'Create ERC20 dividends for token holders at a specific checkpoint', - 'Wrong Module added' - ); - assert.equal(await I_ERC20DividendCheckpointFactory.getTitle.call(), 'ERC20 Dividend Checkpoint', 'Wrong Module added'); - assert.equal( - await I_ERC20DividendCheckpointFactory.getInstructions.call(), - 'Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created', - 'Wrong Module added' - ); - let tags = await I_ERC20DividendCheckpointFactory.getTags.call(); - assert.equal(tags.length, 3); - }); - }); - }); }); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 92ebce81d..f87920419 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -22,864 +22,833 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('EtherDividendCheckpoint', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - let dividendName = '0x546573744469766964656e640000000000000000000000000000000000000000'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let P_EtherDividendCheckpointFactory; - let P_EtherDividendCheckpoint; - let I_EtherDividendCheckpointFactory; - let I_GeneralPermissionManager; - let I_EtherDividendCheckpoint; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_MRProxied; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - let snapId; - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // STEP 4: Deploy the ERC20DividendCheckpoint - P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new( - I_PolyToken.address, - web3.utils.toWei('500', 'ether'), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_EtherDividendCheckpointFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'ERC20DividendCheckpointFactory contract was not deployed' - ); - - // STEP 4: Deploy the EtherDividendCheckpoint - I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_EtherDividendCheckpointFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'EtherDividendCheckpointFactory contract was not deployed' - ); - - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the EtherDividendCheckpointFactory - await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid EtherDividendCheckpointFactory - await I_MRProxied.registerModule(P_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - - EtherDividendCheckpointFactory: ${I_EtherDividendCheckpointFactory.address} - ----------------------------------------------------------------------------- - `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it('Should successfully attach the ERC20DividendCheckpoint with the security token', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); - await catchRevert( - I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { from: token_owner }) - ); - }); - - it('Should successfully attach the EtherDividendCheckpoint with the security token', async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); - const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, '', web3.utils.toWei('500', 'ether'), 0, { - from: token_owner - }); - assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), - 'EtherDividendCheckpoint', - 'EtherDividendCheckpoint module was not added' - ); - P_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it('Should successfully attach the EtherDividendCheckpoint with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, '', 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'EtherDividendCheckpoint', - 'EtherDividendCheckpoint module was not added' - ); - I_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[2].args._module); - }); - }); - - describe('Check Dividend payouts', async () => { - it('Buy some tokens for account_investor1 (1 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Buy some tokens for account_investor2 (2 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); - }); - - it('Should fail in creating the dividend', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { from: token_owner })); - }); - - it('Should fail in creating the dividend', async () => { - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await catchRevert( - I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { - from: token_owner, - value: web3.utils.toWei('1.5', 'ether') - }) - ); - }); - - it('Should fail in creating the dividend', async () => { - let maturity = latestTime() - duration.days(2); - let expiry = latestTime() - duration.days(1); - await catchRevert( - I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { - from: token_owner, - value: web3.utils.toWei('1.5', 'ether') - }) - ); - }); - - it('Set withholding tax of 20% on investor 2', async () => { - await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(20 * 10 ** 16), { from: token_owner }); - }); - - it('Should fail in creating the dividend', async () => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - await catchRevert( - I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', { from: token_owner, value: web3.utils.toWei('1.5', 'ether') }) - ); - }); - - it('Create new dividend', async () => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { - from: token_owner, - value: web3.utils.toWei('1.5', 'ether') - }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, 'Dividend should be created at checkpoint 1'); - assert.equal(tx.logs[0].args._name.toString(), dividendName, 'Dividend name incorrect in event'); - }); - - it('Investor 1 transfers his token balance to investor 2', async () => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner })); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { - // Increase time by 2 day - await increaseTime(duration.days(2)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: account_temp })); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner })); - }); - - it('Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint', async () => { - let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); - await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner }); - let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); - assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('0.8', 'ether')); - //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); - }); - - it('Should not allow reclaiming withholding tax with incorrect index', async () => { - await catchRevert( - I_EtherDividendCheckpoint.withdrawWithholding(300, { from: token_owner, gasPrice: 0 }), - 'tx -> failed because dividend index is not valid' - ); - }); - - it('Issuer reclaims withholding tax', async () => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.2', 'ether')); - }); - - it('No more withholding tax to withdraw', async () => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')); - }); - - it('Buy some tokens for account_temp (1 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - latestTime(), - latestTime(), - latestTime() + duration.days(20), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), 'Failed in adding the investor in whitelist'); - // Mint some tokens - await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_temp)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Create new dividend', async () => { - let maturity = latestTime() + duration.days(1); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { - from: token_owner, - value: web3.utils.toWei('1.5', 'ether') - }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, 'Dividend should be created at checkpoint 2'); - }); - - it('Issuer pushes dividends fails due to passed expiry', async () => { - await increaseTime(duration.days(12)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner })); - }); - - it('Issuer reclaims dividend', async () => { - let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }); - assert.equal(tx.logs[0].args._claimedAmount.toNumber(), web3.utils.toWei('1.5', 'ether')); - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 })); - }); - - it('Still no more withholding tax to withdraw', async () => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')); - }); - - it('Buy some tokens for account_investor3 (7 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it('Create another new dividend', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { - from: token_owner, - value: web3.utils.toWei('11', 'ether') - }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, 'Dividend should be created at checkpoint 3'); - }); - - it('should investor 3 claims dividend - fails bad index', async () => { - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(5, { from: account_investor3, gasPrice: 0 })); - }); - - it('Should investor 3 claims dividend', async () => { - let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); - await I_EtherDividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }); - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); - }); - - it('Still no more withholding tax to withdraw', async () => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')); - }); - - it('should investor 3 claims dividend', async () => { - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 })); - }); - - it('Issuer pushes remainder', async () => { - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); - let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('2.4', 'ether')); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('11', 'ether')); - }); - - it('Issuer withdraws new withholding tax', async () => { - let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(2, { from: token_owner, gasPrice: 0 }); - let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.6', 'ether')); - }); - - it('Investor 2 transfers 1 ETH of his token balance to investor 1', async () => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - }); - - it('Create another new dividend with no value - fails', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - let tx = await I_SecurityToken.createCheckpoint({ from: token_owner }); - await catchRevert( - I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { from: token_owner, value: 0 }) - ); - }); + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_temp; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let P_EtherDividendCheckpointFactory; + let P_EtherDividendCheckpoint; + let I_EtherDividendCheckpointFactory; + let I_GeneralPermissionManager; + let I_EtherDividendCheckpoint; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_MRProxied; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + let snapId; + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const checkpointKey = 4; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - it('Create another new dividend with explicit', async () => { - let maturity = latestTime(); - let expiry = latestTime() - duration.days(10); - await catchRevert( - I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { - from: token_owner, - value: web3.utils.toWei('11', 'ether') - }) - ); - }); + // STEP 5: Deploy the GeneralDelegateManagerFactory - it('Create another new dividend with bad expirty - fails', async () => { - let maturity = latestTime() - duration.days(5); - let expiry = latestTime() - duration.days(2); - await catchRevert( - I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { - from: token_owner, - value: web3.utils.toWei('11', 'ether') - }) - ); - }); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - it('Create another new dividend with bad checkpoint in the future - fails', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(2); - await catchRevert( - I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, { - from: token_owner, - value: web3.utils.toWei('11', 'ether') - }) - ); - }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - it('Should not create dividend with more exclusions than limit', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - await I_SecurityToken.createCheckpoint({ from: token_owner }); - let limit = await I_EtherDividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); - limit = limit.toNumber(); - let addresses = []; - addresses.push(account_temp); - while (limit--) addresses.push(limit); - await catchRevert( - I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, addresses, dividendName, { - from: token_owner, - value: web3.utils.toWei('10', 'ether') - }), - 'tx -> failed because too many address excluded' - ); - }); + // STEP 4: Deploy the ERC20DividendCheckpoint + P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + assert.notEqual( + P_EtherDividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ERC20DividendCheckpointFactory contract was not deployed" + ); - it('Create another new dividend with explicit checkpoint and excluding account_investor1', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - //checkpoint created in above test - let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions( - maturity, - expiry, - 4, - [account_investor1], - dividendName, - { from: token_owner, value: web3.utils.toWei('10', 'ether') } - ); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, 'Dividend should be created at checkpoint 4'); - }); + // STEP 4: Deploy the EtherDividendCheckpoint + I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_EtherDividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "EtherDividendCheckpointFactory contract was not deployed" + ); - it('Non-owner pushes investor 1 - fails', async () => { - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert( - I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1], { - from: account_investor2, - gasPrice: 0 - }) - ); - }); + // Step 6: Deploy the STFactory contract - it('issuer pushes investor 1 with bad dividend index - fails', async () => { - let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert( - I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1], { - from: token_owner, - gasPrice: 0 - }) - ); - }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - it('should calculate dividend before the push dividend payment', async () => { - let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); - let dividendAmount3 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor3); - let dividendAmount_temp = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_temp); - //1 has 1/11th, 2 has 2/11th, 3 has 7/11th, temp has 1/11th, but 1 is excluded - assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei('0', 'ether')); - assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei('0', 'ether')); - assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei('2', 'ether')); - assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei('0.4', 'ether')); - assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei('7', 'ether')); - assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei('0', 'ether')); - assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei('0', 'ether')); - }); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - it('Investor 2 claims dividend', async () => { - let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); - await I_EtherDividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.6', 'ether')); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); - assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); - }); + // Step 7: Deploy the SecurityTokenRegistry contract - it('Should issuer pushes investor 1 and temp investor', async () => { - let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); - await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor1, account_temp], { from: token_owner }); - let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter2 = BigNumber(await web3.eth.getBalance(account_temp)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('1', 'ether')); - //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); - }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - it('should calculate dividend after the push dividend payment', async () => { - let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); - let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); - assert.equal(dividendAmount1[0].toNumber(), 0); - assert.equal(dividendAmount2[0].toNumber(), 0); - }); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - it('Issuer unable to reclaim dividend (expiry not passed)', async () => { - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner })); - }); + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - it('Issuer is able to reclaim dividend after expiry', async () => { - await increaseTime(11 * 24 * 60 * 60); - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, { from: token_owner, gasPrice: 0 })); - }); + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - it('Issuer is able to reclaim dividend after expiry', async () => { - let tokenOwnerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }); - let tokenOwnerAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); - }); + // STEP 5: Register the Modules with the ModuleRegistry contract - it('Issuer is able to reclaim dividend after expiry', async () => { - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 })); - }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - it('Investor 3 unable to pull dividend after expiry', async () => { - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 })); - }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - it("Assign token balance to an address that can't receive funds", async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - I_PolyToken.address, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 500000 - } - ); - // Jump time - await increaseTime(5000); - // Mint some tokens - await I_SecurityToken.mint(I_PolyToken.address, web3.utils.toWei('1', 'ether'), { from: token_owner }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(I_PolyToken.address), web3.utils.toWei('1', 'ether')); - }); + // (C) : Register the EtherDividendCheckpointFactory + await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); - it('Create another new dividend', async () => { - let maturity = latestTime(); - let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], dividendName, { - from: token_owner, - value: web3.utils.toWei('12', 'ether') - }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 6, 'Dividend should be created at checkpoint 6'); - }); + // (C) : Register the Paid EtherDividendCheckpointFactory + await I_MRProxied.registerModule(P_EtherDividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); - it('Should issuer pushes all dividends', async () => { - let investor1BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceBefore = BigNumber(await web3.eth.getBalance(account_temp)); - let tokenBalanceBefore = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); - - await I_EtherDividendCheckpoint.pushDividendPayment(4, 0, 10, { from: token_owner }); - - let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); - let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); - let investor3BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor3)); - let tempBalanceAfter = BigNumber(await web3.eth.getBalance(account_temp)); - let tokenBalanceAfter = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); - - assert.equal(investor1BalanceAfter.sub(investor1BalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), web3.utils.toWei('1.6', 'ether')); - assert.equal(investor3BalanceAfter.sub(investor3BalanceBefore).toNumber(), web3.utils.toWei('7', 'ether')); - assert.equal(tempBalanceAfter.sub(tempBalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(tokenBalanceAfter.sub(tokenBalanceBefore).toNumber(), web3.utils.toWei('0', 'ether')); - - //Check partially claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(4))[5].toNumber(), web3.utils.toWei('11', 'ether')); - }); + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + ModuleRegistryProxy: ${ModuleRegistryProxy.address} + FeatureRegistry: ${FeatureRegistry.address} - it('Should give the right dividend index', async () => { - let index = await I_EtherDividendCheckpoint.getDividendIndex.call(3); - assert.equal(index[0], 2); - }); + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - it('Should give the right dividend index', async () => { - let index = await I_EtherDividendCheckpoint.getDividendIndex.call(8); - assert.equal(index.length, 0); + EtherDividendCheckpointFactory: ${I_EtherDividendCheckpointFactory.address} + ----------------------------------------------------------------------------- + `); }); - it('Get the init data', async () => { - let tx = await I_EtherDividendCheckpoint.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); - }); + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { + + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + await catchRevert(I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + }); + + it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "EtherDividendCheckpoint", + "EtherDividendCheckpoint module was not added" + ); + P_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "EtherDividendCheckpoint", + "EtherDividendCheckpoint module was not added" + ); + I_EtherDividendCheckpoint = EtherDividendCheckpoint.at(tx.logs[2].args._module); + }); + }); + + describe("Check Dividend payouts", async() => { + + it("Buy some tokens for account_investor1 (1 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Buy some tokens for account_investor2 (2 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Should fail in creating the dividend", async() => { + + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner})); + }); + + it("Should fail in creating the dividend", async() => { + + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); + }); + + it("Should fail in creating the dividend", async() => { + + let maturity = latestTime() - duration.days(2); + let expiry = latestTime() - duration.days(1); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); + }); + + it("Set withholding tax of 20% on investor 2", async() => { + await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(20*10**16), {from: token_owner}); + }); + + it("Should fail in creating the dividend", async() => { + + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); + }); + + it("Create new dividend", async() => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); + assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); + }); + + it("Investor 1 transfers his token balance to investor 2", async() => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), {from: account_investor1}); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + + // Increase time by 2 day + await increaseTime(duration.days(2)); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp})); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner})); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); + await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); + let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); + assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); + assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('0.8', 'ether')); + //Check fully claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); + }); + + it("Should not allow reclaiming withholding tax with incorrect index", async() => { + await catchRevert( + I_EtherDividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), + "tx -> failed because dividend index is not valid" + ); + }); + + it("Issuer reclaims withholding tax", async() => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.2', 'ether')) + }); + + it("No more withholding tax to withdraw", async() => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) + }); + + it("Buy some tokens for account_temp (1 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_temp, + latestTime(), + latestTime(), + latestTime() + duration.days(20), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_temp)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Create new dividend", async() => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 2"); + }); + + it("Issuer pushes dividends fails due to passed expiry", async() => { + + await increaseTime(duration.days(12)); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); + }); + + it("Issuer reclaims dividend", async() => { + + let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); + assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000})); + }); + + it("Still no more withholding tax to withdraw", async() => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) + }); + + it("Buy some tokens for account_investor3 (7 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), + web3.utils.toWei('7', 'ether') + ); + }); + + it("Create another new dividend", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 3"); + }); + + it("should investor 3 claims dividend - fails bad index", async() => { + + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0})); + }); + + it("Should investor 3 claims dividend", async() => { + let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); + await I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it("Still no more withholding tax to withdraw", async() => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) + }); + + it("should investor 3 claims dividend", async() => { + + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0})); + }); + + it("Issuer pushes remainder", async() => { + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); + let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('2.4', 'ether')); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + //Check fully claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('11', 'ether')); + }); + + it("Issuer withdraws new withholding tax", async() => { + let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.withdrawWithholding(2, {from: token_owner, gasPrice: 0}); + let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.6', 'ether')) + }); + + it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + }); + + it("Create another new dividend with no value - fails", async() => { + + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: 0})); + }); + + it("Create another new dividend with explicit", async() => { + + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); + }); + + it("Create another new dividend with bad expirty - fails", async() => { + + let maturity = latestTime() - duration.days(5); + let expiry = latestTime() - duration.days(2); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); + }); + + it("Create another new dividend with bad checkpoint in the future - fails", async() => { + + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); + }); + + it("Should not create dividend with more exclusions than limit", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + await I_SecurityToken.createCheckpoint({from: token_owner}); + let limit = await I_EtherDividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); + limit = limit.toNumber(); + let addresses = []; + addresses.push(account_temp); + while(limit--) + addresses.push(limit); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, addresses, dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}), + "tx -> failed because too many address excluded" + ); + }); + + it("Create another new dividend with explicit checkpoint and excluding account_investor1", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + //checkpoint created in above test + let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, [account_investor1], dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 4"); + }); + + it("Non-owner pushes investor 1 - fails", async() => { + + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0})); + }); + + it("issuer pushes investor 1 with bad dividend index - fails", async() => { + + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0})); + }); + + it("should calculate dividend before the push dividend payment", async() => { + let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); + let dividendAmount3 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor3); + let dividendAmount_temp = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_temp); + //1 has 1/11th, 2 has 2/11th, 3 has 7/11th, temp has 1/11th, but 1 is excluded + assert.equal(dividendAmount1[0].toNumber(), web3.utils.toWei("0", "ether")); + assert.equal(dividendAmount1[1].toNumber(), web3.utils.toWei("0", "ether")); + assert.equal(dividendAmount2[0].toNumber(), web3.utils.toWei("2", "ether")); + assert.equal(dividendAmount2[1].toNumber(), web3.utils.toWei("0.4", "ether")); + assert.equal(dividendAmount3[0].toNumber(), web3.utils.toWei("7", "ether")); + assert.equal(dividendAmount3[1].toNumber(), web3.utils.toWei("0", "ether")); + assert.equal(dividendAmount_temp[0].toNumber(), web3.utils.toWei("1", "ether")); + assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0", "ether")); + }); + + it("Investor 2 claims dividend", async() => { + let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); + await I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor2, gasPrice: 0}); + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); + assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.6', 'ether')); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); + assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); + }); + + it("Should issuer pushes investor 1 and temp investor", async() => { + let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); + await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor1, account_temp], {from: token_owner}); + let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter2 = BigNumber(await web3.eth.getBalance(account_temp)); + assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); + assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); + assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('1', 'ether')); + //Check fully claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); + }); + + it("should calculate dividend after the push dividend payment", async() => { + let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); + let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); + assert.equal(dividendAmount1[0].toNumber(), 0); + assert.equal(dividendAmount2[0].toNumber(), 0); + }); + + it("Issuer unable to reclaim dividend (expiry not passed)", async() => { + + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner})); + }); + + it("Issuer is able to reclaim dividend after expiry", async() => { + + await increaseTime(11 * 24 * 60 * 60); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0})); + }); + + it("Issuer is able to reclaim dividend after expiry", async() => { + let tokenOwnerBalance = BigNumber(await web3.eth.getBalance(token_owner)); + await I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); + let tokenOwnerAfter = BigNumber(await web3.eth.getBalance(token_owner)); + assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + + it("Issuer is able to reclaim dividend after expiry", async() => { + + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0})); + }); + + it("Investor 3 unable to pull dividend after expiry", async() => { + + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0})); + }); + + it("Assign token balance to an address that can't receive funds", async() => { + + let tx = await I_GeneralTransferManager.modifyWhitelist( + I_PolyToken.address, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + }); + // Jump time + await increaseTime(5000); + // Mint some tokens + await I_SecurityToken.mint(I_PolyToken.address, web3.utils.toWei('1', 'ether'), { from: token_owner }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(I_PolyToken.address), web3.utils.toWei('1', 'ether')); + }); + + it("Create another new dividend", async() => { + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], dividendName, {from: token_owner, value: web3.utils.toWei('12', 'ether')}); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 6, "Dividend should be created at checkpoint 6"); + }); + + it("Should issuer pushes all dividends", async() => { + let investor1BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceBefore = BigNumber(await web3.eth.getBalance(account_temp)); + let tokenBalanceBefore = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); + + await I_EtherDividendCheckpoint.pushDividendPayment(4, 0, 10, {from: token_owner}); + + let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); + let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); + let investor3BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor3)); + let tempBalanceAfter = BigNumber(await web3.eth.getBalance(account_temp)); + let tokenBalanceAfter = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); + + assert.equal(investor1BalanceAfter.sub(investor1BalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), web3.utils.toWei('1.6', 'ether')); + assert.equal(investor3BalanceAfter.sub(investor3BalanceBefore).toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(tempBalanceAfter.sub(tempBalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(tokenBalanceAfter.sub(tokenBalanceBefore).toNumber(), web3.utils.toWei('0', 'ether')); + + //Check partially claimed + assert.equal((await I_EtherDividendCheckpoint.dividends(4))[5].toNumber(), web3.utils.toWei('11', 'ether')); + }); + + it("Should give the right dividend index", async() => { + let index = await I_EtherDividendCheckpoint.getDividendIndex.call(3); + assert.equal(index[0], 2); + }); + + it("Should give the right dividend index", async() => { + let index = await I_EtherDividendCheckpoint.getDividendIndex.call(8); + assert.equal(index.length, 0); + }); + + it("Get the init data", async() => { + let tx = await I_EtherDividendCheckpoint.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + }); + + it("Should get the listed permissions", async() => { + let tx = await I_EtherDividendCheckpoint.getPermissions.call(); + assert.equal(tx.length,1); + }); + + describe("Test cases for the EtherDividendCheckpointFactory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); + assert.equal(await I_EtherDividendCheckpointFactory.getType.call(), 4); + assert.equal(await I_EtherDividendCheckpointFactory.getVersion.call(), "1.0.0"); + assert.equal(web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()) + .replace(/\u0000/g, ''), + "EtherDividendCheckpoint", + "Wrong Module added"); + assert.equal(await I_EtherDividendCheckpointFactory.getDescription.call(), + "Create ETH dividends for token holders at a specific checkpoint", + "Wrong Module added"); + assert.equal(await I_EtherDividendCheckpointFactory.getTitle.call(), + "Ether Dividend Checkpoint", + "Wrong Module added"); + assert.equal(await I_EtherDividendCheckpointFactory.getInstructions.call(), + "Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", + "Wrong Module added"); + let tags = await I_EtherDividendCheckpointFactory.getTags.call(); + assert.equal(tags.length, 3); + + }); + }); - it('Should get the listed permissions', async () => { - let tx = await I_EtherDividendCheckpoint.getPermissions.call(); - assert.equal(tx.length, 1); }); - describe('Test cases for the EtherDividendCheckpointFactory', async () => { - it('should get the exact details of the factory', async () => { - assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_EtherDividendCheckpointFactory.getType.call(), 4); - assert.equal(await I_EtherDividendCheckpointFactory.getVersion.call(), '1.0.0'); - assert.equal( - web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()).replace(/\u0000/g, ''), - 'EtherDividendCheckpoint', - 'Wrong Module added' - ); - assert.equal( - await I_EtherDividendCheckpointFactory.getDescription.call(), - 'Create ETH dividends for token holders at a specific checkpoint', - 'Wrong Module added' - ); - assert.equal(await I_EtherDividendCheckpointFactory.getTitle.call(), 'Ether Dividend Checkpoint', 'Wrong Module added'); - assert.equal( - await I_EtherDividendCheckpointFactory.getInstructions.call(), - 'Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created', - 'Wrong Module added' - ); - let tags = await I_EtherDividendCheckpointFactory.getTags.call(); - assert.equal(tags.length, 3); - }); - }); - }); }); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index d3654f9cf..d7b042dd6 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -1,12 +1,12 @@ import latestTime from './helpers/latestTime'; -import { signData } from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; +import {signData} from './helpers/signData'; +import { pk } from './helpers/testprivateKey'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -24,212 +24,208 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('GeneralPermissionManager', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let token_owner_pk; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_delegate; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let P_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let P_GeneralPermissionManager; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_DummySTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_MRProxied; - let I_STRProxied; - let I_DummySTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - const delegateDetails = 'Hello I am legit delegate'; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); - const someString = 'A string which is not used'; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - token_owner_pk = pk.account_1; - - account_investor1 = accounts[8]; - account_investor2 = accounts[9]; - account_delegate = accounts[7]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let token_owner_pk; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_delegate; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let P_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let P_GeneralPermissionManager; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_DummySTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_MRProxied; + let I_STRProxied; + let I_DummySTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + const delegateDetails = "Hello I am legit delegate"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // Dummy STO details + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei('10', 'ether'); + const someString = "A string which is not used"; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + token_owner_pk = pk.account_1; + + account_investor1 = accounts[8]; + account_investor2 = accounts[9]; + account_delegate = accounts[7]; + + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 5: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); + // STEP 6: Deploy the GeneralDelegateManagerFactory - // STEP 6: Deploy the GeneralDelegateManagerFactory + P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); - P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new( - I_PolyToken.address, - web3.utils.toWei('500', 'ether'), - 0, - 0, - { from: account_polymath } - ); + assert.notEqual( + P_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - assert.notEqual( - P_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); + // STEP 7: Deploy the DummySTOFactory - // STEP 7: Deploy the DummySTOFactory + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "DummySTOFactory contract was not deployed" + ); - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'DummySTOFactory contract was not deployed' - ); - // Step 8: Deploy the STFactory contract + // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - // Step 9: Deploy the SecurityTokenRegistry contract + // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - // STEP 8: Register the Modules with the ModuleRegistry contract + // STEP 8: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the Paid GeneralDelegateManagerFactory - await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the Paid GeneralDelegateManagerFactory + await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -245,163 +241,158 @@ contract('GeneralPermissionManager', accounts => { DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it("Should successfully attach the General permission manager factory with the security token", async () => { + + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + await catchRevert(I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + }); + + it("Should successfully attach the General permission manager factory with the security token", async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "GeneralPermissionManager", + "GeneralPermissionManagerFactory module was not added" + ); + P_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it("Should successfully attach the General permission manager factory with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "GeneralPermissionManager", + "GeneralPermissionManagerFactory module was not added" + ); + I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); + }); }); - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + describe("General Permission Manager test cases", async() => { + + it("Get the init data", async() => { + let tx = await I_GeneralPermissionManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + }); + + it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async() => { + + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1})); + }); + + it("Should fail to provide the permission-- because delegate is not yet added", async() => { + + await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner})); + }); + + it("Should add the permission to the delegate", async() => { + let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); + assert.equal(tx.logs[0].args._delegate, account_delegate); + }); + + it("Should fail to provide the permission", async() => { + + await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1})); + }); + + it("Should check the permission", async() => { + assert.isFalse(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); + }); + + it("Should provide the permission", async() => { + let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); + assert.equal(tx.logs[0].args._delegate, account_delegate); + }); + + it("Should check the permission", async() => { + assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); + }); + + it("Should check the delegate details", async() => { + assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)) + .replace(/\u0000/g, ''), + delegateDetails, + "Wrong delegate address get checked"); + }); + + it("Should get the permission of the general permission manager contract", async() => { + let tx = await I_GeneralPermissionManager.getPermissions.call(); + assert.equal(web3.utils.toAscii(tx[0]) + .replace(/\u0000/g, ''), + "CHANGE_PERMISSION", + "Wrong permissions"); + }); }); - it('Should successfully attach the General permission manager factory with the security token', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); - await catchRevert( - I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, '0x', web3.utils.toWei('500', 'ether'), 0, { - from: token_owner - }) - ); - }); - - it('Should successfully attach the General permission manager factory with the security token', async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); - const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, '0x', web3.utils.toWei('500', 'ether'), 0, { - from: token_owner - }); - assert.equal(tx.logs[3].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), - 'GeneralPermissionManager', - 'GeneralPermissionManagerFactory module was not added' - ); - P_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it('Should successfully attach the General permission manager factory with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '0x', 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'GeneralPermissionManager', - 'GeneralPermissionManagerFactory module was not added' - ); - I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); - }); - }); - - describe('General Permission Manager test cases', async () => { - it('Get the init data', async () => { - let tx = await I_GeneralPermissionManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); + describe("General Permission Manager Factory test cases", async() => { + it("should get the exact details of the factory", async() => { + assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); + assert.equal(await I_GeneralPermissionManagerFactory.getType.call(),1); + assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), "1.0.0"); + assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) + .replace(/\u0000/g, ''), + "GeneralPermissionManager", + "Wrong Module added"); + assert.equal(await I_GeneralPermissionManagerFactory.getDescription.call(), + "Manage permissions within the Security Token and attached modules", + "Wrong Module added"); + assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), + "General Permission Manager", + "Wrong Module added"); + assert.equal(await I_GeneralPermissionManagerFactory.getInstructions.call(), + "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", + "Wrong Module added"); + + }); + + it("Should get the tags of the factory", async() => { + let tags = await I_GeneralPermissionManagerFactory.getTags.call(); + assert.equal(tags.length,0); + }); }); - it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async () => { - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1 })); - }); - - it('Should fail to provide the permission-- because delegate is not yet added', async () => { - await catchRevert( - I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'WHITELIST', true, { - from: token_owner - }) - ); - }); - - it('Should add the permission to the delegate', async () => { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); - assert.equal(tx.logs[0].args._delegate, account_delegate); - }); - - it('Should fail to provide the permission', async () => { - await catchRevert( - I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'WHITELIST', true, { - from: account_investor1 - }) - ); - }); - - it('Should check the permission', async () => { - assert.isFalse( - await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, 'WHITELIST') - ); - }); - - it('Should provide the permission', async () => { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'WHITELIST', true, { - from: token_owner - }); - assert.equal(tx.logs[0].args._delegate, account_delegate); - }); - - it('Should check the permission', async () => { - assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, 'WHITELIST')); - }); - - it('Should check the delegate details', async () => { - assert.equal( - web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)).replace(/\u0000/g, ''), - delegateDetails, - 'Wrong delegate address get checked' - ); - }); - - it('Should get the permission of the general permission manager contract', async () => { - let tx = await I_GeneralPermissionManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ''), 'CHANGE_PERMISSION', 'Wrong permissions'); - }); - }); - - describe('General Permission Manager Factory test cases', async () => { - it('should get the exact details of the factory', async () => { - assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(), 0); - assert.equal(await I_GeneralPermissionManagerFactory.getType.call(), 1); - assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), '1.0.0'); - assert.equal( - web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()).replace(/\u0000/g, ''), - 'GeneralPermissionManager', - 'Wrong Module added' - ); - assert.equal( - await I_GeneralPermissionManagerFactory.getDescription.call(), - 'Manage permissions within the Security Token and attached modules', - 'Wrong Module added' - ); - assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), 'General Permission Manager', 'Wrong Module added'); - assert.equal( - await I_GeneralPermissionManagerFactory.getInstructions.call(), - 'Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.', - 'Wrong Module added' - ); - }); - - it('Should get the tags of the factory', async () => { - let tags = await I_GeneralPermissionManagerFactory.getTags.call(); - assert.equal(tags.length, 0); - }); - }); }); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index e8dad9143..50c587aa4 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -1,12 +1,12 @@ import latestTime from './helpers/latestTime'; import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { signData } from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; +import {signData} from './helpers/signData'; +import { pk } from './helpers/testprivateKey'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -24,194 +24,195 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('GeneralTransferManager', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let token_owner_pk; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_delegate; - let account_affiliates1; - let account_affiliates2; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_DummySTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_STRProxied; - let I_MRProxied; - let I_DummySTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); - const someString = 'A string which is not used'; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - token_owner_pk = pk.account_1; - - account_investor1 = accounts[8]; - account_investor2 = accounts[9]; - account_delegate = accounts[7]; - account_investor4 = accounts[6]; - - account_affiliates1 = accounts[3]; - account_affiliates2 = accounts[4]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - // STEP 3: Deploy the GeneralDelegateManagerFactory + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let token_owner_pk; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_delegate; + let account_affiliates1; + let account_affiliates2; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_DummySTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_STRProxied; + let I_MRProxied; + let I_DummySTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // Dummy STO details + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei('10', 'ether'); + const someString = "A string which is not used"; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + token_owner_pk = pk.account_1; + + account_investor1 = accounts[8]; + account_investor2 = accounts[9]; + account_delegate = accounts[7]; + account_investor4 = accounts[6]; + + account_affiliates1 = accounts[3]; + account_affiliates2 = accounts[4]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 3: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 4: Deploy the DummySTOFactory + + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "DummySTOFactory contract was not deployed" + ); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + // Step 8: Deploy the STFactory contract - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - // STEP 4: Deploy the DummySTOFactory + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + // Step 9: Deploy the SecurityTokenRegistry contract - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'DummySTOFactory contract was not deployed' - ); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - // Step 8: Deploy the STFactory contract + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - // Step 9: Deploy the SecurityTokenRegistry contract + // STEP 5: Register the Modules with the ModuleRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -227,479 +228,506 @@ contract('GeneralTransferManager', accounts => { DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it('Should whitelist the affiliates before the STO attached', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelistMulti( - [account_affiliates1, account_affiliates2], - [latestTime() + duration.days(30), latestTime() + duration.days(30)], - [latestTime() + duration.days(90), latestTime() + duration.days(90)], - [latestTime() + duration.years(1), latestTime() + duration.years(1)], - [false, false], - { - from: account_issuer, - gas: 6000000 - } - ); - assert.equal(tx.logs[0].args._investor, account_affiliates1); - assert.equal(tx.logs[1].args._investor, account_affiliates2); }); - it('Should mint the tokens to the affiliates', async () => { - await I_SecurityToken.mintMulti([account_affiliates1, account_affiliates2], [100 * Math.pow(10, 18), 100 * Math.pow(10, 18)], { - from: account_issuer, - gas: 6000000 - }); - assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - }); - - it('Should successfully attach the STO factory with the security token', async () => { - let bytesSTO = encodeModuleCall(STOParameters, [ - latestTime() + duration.seconds(1000), - latestTime() + duration.days(40), - cap, - someString - ]); - const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), stoKey, "DummySTO doesn't get deployed"); - assert.equal(web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), 'DummySTO', 'DummySTOFactory module was not added'); - I_DummySTO = DummySTO.at(tx.logs[2].args._module); - }); - - it('Should successfully attach the permission manager factory with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, 0, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'GeneralPermissionManager', - 'GeneralPermissionManager module was not added' - ); - I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); - }); - }); - - describe('Buy tokens using on-chain whitelist', async () => { - it('Should buy the tokens -- Failed due to investor is not in the whitelist', async () => { - await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }); - - it('Should Buy the tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Should fail in buying the token from the STO', async () => { - await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }); - - it('Should fail in investing the money in STO -- expiry limit reached', async () => { - await increaseTime(duration.days(10)); - - await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }); - }); - - describe('Buy tokens using off-chain whitelist', async () => { - it('Should buy the tokens -- Failed due to investor is not in the whitelist', async () => { - await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }); - - it('Should buy the tokens -- Failed due to incorrect signature input', async () => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime(); - let validTo = latestTime() + duration.days(5); - const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - - await catchRevert( - I_GeneralTransferManager.modifyWhitelistSigned(account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, v, r, s, { - from: account_investor2, - gas: 6000000 + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + it("Should whitelist the affiliates before the STO attached", async() => { + let tx = await I_GeneralTransferManager.modifyWhitelistMulti( + [account_affiliates1, account_affiliates2], + [(latestTime() + duration.days(30)),(latestTime() + duration.days(30))], + [(latestTime() + duration.days(90)),(latestTime() + duration.days(90))], + [(latestTime() + duration.years(1)),(latestTime() + duration.years(1))], + [false, false], + { + from: account_issuer, + gas: 6000000 + }); + assert.equal(tx.logs[0].args._investor, account_affiliates1); + assert.equal(tx.logs[1].args._investor, account_affiliates2); + }); + + it("Should mint the tokens to the affiliates", async () => { + await I_SecurityToken.mintMulti([account_affiliates1, account_affiliates2], [(100 * Math.pow(10, 18)), (100 * Math.pow(10, 18))], { from: account_issuer, gas:6000000 }); + assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + }); + + it("Should successfully attach the STO factory with the security token", async () => { + let bytesSTO = encodeModuleCall(STOParameters, [latestTime() + duration.seconds(1000), latestTime() + duration.days(40), cap, someString]); + const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), stoKey, "DummySTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "DummySTO", + "DummySTOFactory module was not added" + ); + I_DummySTO = DummySTO.at(tx.logs[2].args._module); + }); + + it("Should successfully attach the permission manager factory with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, 0, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "GeneralPermissionManager", + "GeneralPermissionManager module was not added" + ); + I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); + }); + + }); + + describe("Buy tokens using on-chain whitelist", async() => { + + it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { + + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + }); + + it("Should Buy the tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should fail in buying the token from the STO", async() => { + + await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + }); + + it("Should fail in investing the money in STO -- expiry limit reached", async() => { + + await increaseTime(duration.days(10)); + + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); }) - ); - }); - it('Should buy the tokens -- Failed due to incorrect signature timing', async () => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime() - 100; - let validTo = latestTime() - 1; - const sig = signData( - I_GeneralTransferManager.address, - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - token_owner_pk - ); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - - await catchRevert( - I_GeneralTransferManager.modifyWhitelistSigned(account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, v, r, s, { - from: account_investor2, - gas: 6000000 - }) - ); }); - it('Should buy the tokens -- Failed due to incorrect signature signer', async () => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime(); - let validTo = latestTime() + 60 * 60; - - const sig = signData( - account_investor2, - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200' - ); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - - await catchRevert( - I_GeneralTransferManager.modifyWhitelistSigned(account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, v, r, s, { - from: account_investor2, - gas: 6000000 - }) - ); + describe("Buy tokens using off-chain whitelist", async() => { + + it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { + + await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner })); + }); + + it("Should buy the tokens -- Failed due to incorrect signature input", async() => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime(); + let validTo = latestTime() + duration.days(5); + const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + + + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + })); + + }); + + it("Should buy the tokens -- Failed due to incorrect signature timing", async() => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime() - 100; + let validTo = latestTime() - 1; + const sig = signData(I_GeneralTransferManager.address, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + + + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + })); + + }); + + it("Should buy the tokens -- Failed due to incorrect signature signer", async() => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime(); + let validTo = latestTime() + (60 * 60); + + const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200'); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + + + await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + })); + + }); + + it("Should Buy the tokens", async() => { + // Add the Investor in to the whitelist + //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk + let validFrom = latestTime(); + let validTo = latestTime() + duration.days(5); + const sig = signData(I_GeneralTransferManager.address, account_investor2, latestTime(), latestTime() + duration.days(80), expiryTime + duration.days(200), true, validFrom, validTo, token_owner_pk); + + const r = `0x${sig.r.toString('hex')}`; + const s = `0x${sig.s.toString('hex')}`; + const v = sig.v; + let tx = await I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + latestTime(), + latestTime() + duration.days(80), + expiryTime + duration.days(200), + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(10000); + // Mint some tokens + + await I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + + }); + + it("Should fail in changing the signing address", async() => { + + await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_investor4})); + }); + + it("Should get the permission", async() => { + let perm = await I_GeneralTransferManager.getPermissions.call(); + assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), "WHITELIST"); + assert.equal(web3.utils.toAscii(perm[1]).replace(/\u0000/g, ''), "FLAGS"); + }); + + it("Should provide the permission and change the signing address", async() => { + let log = await I_GeneralPermissionManager.addPermission(account_delegate, "My details", {from: token_owner}); + assert.equal(log.logs[0].args._delegate, account_delegate); + + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FLAGS", true, {from: token_owner}); + + assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "FLAGS")); + + let tx = await I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_delegate}); + assert.equal(tx.logs[0].args._signingAddress, account_polymath); + }); + + it("Should fail to pull fees as no budget set", async() => { + + + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); + }); + + it("Should set a budget for the GeneralTransferManager", async() => { + await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), {from: token_owner}); + + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); + await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); + await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), {from: token_owner}); + }); + + + it("Factory owner should pull fees - fails as not permissioned by issuer", async() => { + + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate})); + }); + + it("Should change the Issuance address", async() => { + let tx = await I_GeneralTransferManager.changeIssuanceAddress(account_investor2, {from: account_delegate}); + assert.equal(tx.logs[0].args._issuanceAddress, account_investor2); + }); + + it("Should unpause the transfers", async() => { + await I_GeneralTransferManager.unpause({from: token_owner}); + + assert.isFalse(await I_GeneralTransferManager.paused.call()); + }); + + it("Should get the init function", async() => { + let byte = await I_GeneralTransferManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); + }); + + }); + + describe("WhiteList that addresses", async () => { + + it("Should fail in adding the investors in whitelist", async() => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime, toTime], + [expiryTime, expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + )); + }); + + it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime], + [toTime, toTime], + [expiryTime, expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + )); + }); + + it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime], + [expiryTime, expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + )); + }); + + it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime, toTime], + [expiryTime], + [true, true], + { + from: account_delegate, + gas: 6000000 + } + )); + }); + + it("Should successfully add the investors in whitelist", async() => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(20); + let expiryTime = toTime + duration.days(10); + + let tx = await I_GeneralTransferManager.modifyWhitelistMulti( + [account_investor3, account_investor4], + [fromTime, fromTime], + [toTime, toTime], + [expiryTime, expiryTime], + [true, true], + { + from: token_owner, + gas: 6000000 + } + ); + assert.equal(tx.logs[1].args._investor, account_investor4); + }); + }); + + describe("General Transfer Manager Factory test cases", async() => { + + it("Should get the exact details of the factory", async() => { + assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(),0); + assert.equal(await I_GeneralTransferManagerFactory.getType.call(),2); + assert.equal(web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()) + .replace(/\u0000/g, ''), + "GeneralTransferManager", + "Wrong Module added"); + assert.equal(await I_GeneralTransferManagerFactory.getDescription.call(), + "Manage transfers using a time based whitelist", + "Wrong Module added"); + assert.equal(await I_GeneralTransferManagerFactory.getTitle.call(), + "General Transfer Manager", + "Wrong Module added"); + assert.equal(await I_GeneralTransferManagerFactory.getInstructions.call(), + "Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters.", + "Wrong Module added"); + + }); + + it("Should get the tags of the factory", async() => { + let tags = await I_GeneralTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "General"); + }); + }); + + describe("Dummy STO Factory test cases", async() => { + it("should get the exact details of the factory", async() => { + assert.equal(await I_DummySTOFactory.setupCost.call(),0); + assert.equal(await I_DummySTOFactory.getType.call(),3); + assert.equal(web3.utils.toAscii(await I_DummySTOFactory.getName.call()) + .replace(/\u0000/g, ''), + "DummySTO", + "Wrong Module added"); + assert.equal(await I_DummySTOFactory.getDescription.call(), + "Dummy STO", + "Wrong Module added"); + assert.equal(await I_DummySTOFactory.getTitle.call(), + "Dummy STO", + "Wrong Module added"); + assert.equal(await I_DummySTOFactory.getInstructions.call(), + "Dummy STO - you can mint tokens at will", + "Wrong Module added"); + + }); + + it("Should get the tags of the factory", async() => { + let tags = await I_DummySTOFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "Dummy"); + }); + }); + + describe("Test cases for the get functions of the dummy sto", async() => { + + it("Should get the raised amount of ether", async() => { + assert.equal(await I_DummySTO.getRaised.call(0), web3.utils.toWei('0','ether')); + }); + + it("Should get the raised amount of poly", async() => { + assert.equal((await I_DummySTO.getRaised.call(1)).toNumber(), web3.utils.toWei('0','ether')); + }); + + it("Should get the investors", async() => { + assert.equal((await I_DummySTO.investorCount.call()).toNumber(), 2); + }); + + it("Should get the listed permissions", async() => { + let tx = await I_DummySTO.getPermissions.call(); + assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ''), "ADMIN"); + }); }); - it('Should Buy the tokens', async () => { - // Add the Investor in to the whitelist - //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk - let validFrom = latestTime(); - let validTo = latestTime() + duration.days(5); - const sig = signData( - I_GeneralTransferManager.address, - account_investor2, - latestTime(), - latestTime() + duration.days(80), - expiryTime + duration.days(200), - true, - validFrom, - validTo, - token_owner_pk - ); - - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; - const v = sig.v; - let tx = await I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - latestTime(), - latestTime() + duration.days(80), - expiryTime + duration.days(200), - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(10000); - // Mint some tokens - - await I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Should fail in changing the signing address', async () => { - await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, { from: account_investor4 })); - }); - - it('Should get the permission', async () => { - let perm = await I_GeneralTransferManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), 'WHITELIST'); - assert.equal(web3.utils.toAscii(perm[1]).replace(/\u0000/g, ''), 'FLAGS'); - }); - - it('Should provide the permission and change the signing address', async () => { - let log = await I_GeneralPermissionManager.addPermission(account_delegate, 'My details', { from: token_owner }); - assert.equal(log.logs[0].args._delegate, account_delegate); - - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, 'FLAGS', true, { - from: token_owner - }); - - assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, 'FLAGS')); - - let tx = await I_GeneralTransferManager.changeSigningAddress(account_polymath, { from: account_delegate }); - assert.equal(tx.logs[0].args._signingAddress, account_polymath); - }); - - it('Should fail to pull fees as no budget set', async () => { - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1', 'ether'), { from: account_polymath })); - }); - - it('Should set a budget for the GeneralTransferManager', async () => { - await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), { from: token_owner }); - - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1', 'ether'), { from: account_polymath })); - await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); - await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), { from: token_owner }); - }); - - it('Factory owner should pull fees - fails as not permissioned by issuer', async () => { - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1', 'ether'), { from: account_delegate })); - }); - - it('Should change the Issuance address', async () => { - let tx = await I_GeneralTransferManager.changeIssuanceAddress(account_investor2, { from: account_delegate }); - assert.equal(tx.logs[0].args._issuanceAddress, account_investor2); - }); - - it('Should unpause the transfers', async () => { - await I_GeneralTransferManager.unpause({ from: token_owner }); - - assert.isFalse(await I_GeneralTransferManager.paused.call()); - }); - - it('Should get the init function', async () => { - let byte = await I_GeneralTransferManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); - }); - }); - - describe('WhiteList that addresses', async () => { - it('Should fail in adding the investors in whitelist', async () => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert( - I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime, toTime], - [expiryTime, expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - ) - ); - }); - - it('Should fail in adding the investors in whitelist -- array length mismatch', async () => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert( - I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime], - [toTime, toTime], - [expiryTime, expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - ) - ); - }); - - it('Should fail in adding the investors in whitelist -- array length mismatch', async () => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert( - I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime], - [expiryTime, expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - ) - ); - }); - - it('Should fail in adding the investors in whitelist -- array length mismatch', async () => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - await catchRevert( - I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime, toTime], - [expiryTime], - [true, true], - { - from: account_delegate, - gas: 6000000 - } - ) - ); - }); - - it('Should successfully add the investors in whitelist', async () => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(20); - let expiryTime = toTime + duration.days(10); - - let tx = await I_GeneralTransferManager.modifyWhitelistMulti( - [account_investor3, account_investor4], - [fromTime, fromTime], - [toTime, toTime], - [expiryTime, expiryTime], - [true, true], - { - from: token_owner, - gas: 6000000 - } - ); - assert.equal(tx.logs[1].args._investor, account_investor4); - }); - }); - - describe('General Transfer Manager Factory test cases', async () => { - it('Should get the exact details of the factory', async () => { - assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(), 0); - assert.equal(await I_GeneralTransferManagerFactory.getType.call(), 2); - assert.equal( - web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()).replace(/\u0000/g, ''), - 'GeneralTransferManager', - 'Wrong Module added' - ); - assert.equal( - await I_GeneralTransferManagerFactory.getDescription.call(), - 'Manage transfers using a time based whitelist', - 'Wrong Module added' - ); - assert.equal(await I_GeneralTransferManagerFactory.getTitle.call(), 'General Transfer Manager', 'Wrong Module added'); - assert.equal( - await I_GeneralTransferManagerFactory.getInstructions.call(), - 'Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters.', - 'Wrong Module added' - ); - }); - - it('Should get the tags of the factory', async () => { - let tags = await I_GeneralTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'General'); - }); - }); - - describe('Dummy STO Factory test cases', async () => { - it('should get the exact details of the factory', async () => { - assert.equal(await I_DummySTOFactory.setupCost.call(), 0); - assert.equal(await I_DummySTOFactory.getType.call(), 3); - assert.equal(web3.utils.toAscii(await I_DummySTOFactory.getName.call()).replace(/\u0000/g, ''), 'DummySTO', 'Wrong Module added'); - assert.equal(await I_DummySTOFactory.getDescription.call(), 'Dummy STO', 'Wrong Module added'); - assert.equal(await I_DummySTOFactory.getTitle.call(), 'Dummy STO', 'Wrong Module added'); - assert.equal(await I_DummySTOFactory.getInstructions.call(), 'Dummy STO - you can mint tokens at will', 'Wrong Module added'); - }); - - it('Should get the tags of the factory', async () => { - let tags = await I_DummySTOFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Dummy'); - }); - }); - - describe('Test cases for the get functions of the dummy sto', async () => { - it('Should get the raised amount of ether', async () => { - assert.equal(await I_DummySTO.getRaised.call(0), web3.utils.toWei('0', 'ether')); - }); - - it('Should get the raised amount of poly', async () => { - assert.equal((await I_DummySTO.getRaised.call(1)).toNumber(), web3.utils.toWei('0', 'ether')); - }); - - it('Should get the investors', async () => { - assert.equal((await I_DummySTO.investorCount.call()).toNumber(), 2); - }); - - it('Should get the listed permissions', async () => { - let tx = await I_DummySTO.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ''), 'ADMIN'); - }); - }); }); diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index a1a91144a..9369f3eba 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -1,6 +1,6 @@ import { encodeProxyCall, encodeModuleCall } from './encodeCall'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -15,145 +15,151 @@ const PolyToken = artifacts.require('./PolyToken.sol'); const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port - -// Contract Instance Declaration -let I_GeneralTransferManagerFactory; -let I_GeneralTransferManager; -let I_ModuleRegistryProxy; -let I_ModuleRegistry; -let I_FeatureRegistry; -let I_SecurityTokenRegistry; -let I_SecurityToken; -let I_PolyToken; -let I_STFactory; -let I_PolymathRegistry; -let I_SecurityTokenRegistryProxy; -let I_STRProxied; -let I_MRProxied; - -// Initial fee for ticker registry and security token registry -const initRegFee = web3.utils.toWei('250'); - -const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; -const MRProxyParameters = ['address', 'address']; +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + + // Contract Instance Declaration + let I_GeneralTransferManagerFactory; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_SecurityToken; + let I_PolyToken; + let I_STFactory; + let I_PolymathRegistry; + let I_SecurityTokenRegistryProxy; + let I_STRProxied; + let I_MRProxied; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; export async function setUpPolymathNetwork(account_polymath, token_owner) { - // ----------- POLYMATH NETWORK Configuration ------------ - // Step 1: Deploy the PolyToken and PolymathRegistry - let a = await deployPolyRegistryAndPolyToken(account_polymath, token_owner); - // Step 2: Deploy the FeatureRegistry - let b = await deployFeatureRegistry(account_polymath); - // STEP 3: Deploy the ModuleRegistry - let c = await deployModuleRegistry(account_polymath); - // STEP 4: Deploy the GeneralTransferManagerFactory - let d = await deployGTM(account_polymath); - // Step 6: Deploy the STversionProxy contract - let e = await deploySTFactory(account_polymath); - // Step 7: Deploy the SecurityTokenRegistry - let f = await deploySTR(account_polymath); - // Step 8: update the registries addresses from the PolymathRegistry contract - await setInPolymathRegistry(account_polymath); - // STEP 9: Register the Modules with the ModuleRegistry contract - await registerGTM(account_polymath); - let tempArray = new Array(a, b, c, d, e, f); - return mergeReturn(tempArray); + // ----------- POLYMATH NETWORK Configuration ------------ + // Step 1: Deploy the PolyToken and PolymathRegistry + let a = await deployPolyRegistryAndPolyToken(account_polymath, token_owner); + // Step 2: Deploy the FeatureRegistry + let b = await deployFeatureRegistry(account_polymath); + // STEP 3: Deploy the ModuleRegistry + let c = await deployModuleRegistry(account_polymath); + // STEP 4: Deploy the GeneralTransferManagerFactory + let d = await deployGTM(account_polymath); + // Step 6: Deploy the STversionProxy contract + let e = await deploySTFactory(account_polymath); + // Step 7: Deploy the SecurityTokenRegistry + let f = await deploySTR(account_polymath); + // Step 8: update the registries addresses from the PolymathRegistry contract + await setInPolymathRegistry(account_polymath); + // STEP 9: Register the Modules with the ModuleRegistry contract + await registerGTM(account_polymath); + let tempArray = new Array(a, b, c, d, e, f); + return mergeReturn(tempArray); + } + function mergeReturn(returnData) { - let returnArray = new Array(); - for (let i = 0; i < returnData.length; i++) { - for (let j = 0; j < returnData[i].length; j++) { - returnArray.push(returnData[i][j]); + let returnArray = new Array(); + for (let i = 0; i < returnData.length; i++) { + for (let j = 0; j < returnData[i].length; j++) { + returnArray.push(returnData[i][j]); + } } - } - return returnArray; + return returnArray; + } + async function deployPolyRegistryAndPolyToken(account_polymath, token_owner) { - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - return new Array(I_PolymathRegistry, I_PolyToken); + return new Array(I_PolymathRegistry, I_PolyToken); } async function deployFeatureRegistry(account_polymath) { - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - return new Array(I_FeatureRegistry); + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + return new Array(I_FeatureRegistry) } async function deployModuleRegistry(account_polymath) { - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - return new Array(I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied); + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + return new Array(I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied); } async function deployGTM(account_polymath) { - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - return new Array(I_GeneralTransferManagerFactory); + return new Array(I_GeneralTransferManagerFactory); } async function deploySTFactory(account_polymath) { - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - return new Array(I_STFactory); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + return new Array(I_STFactory); } async function deploySTR(account_polymath) { - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - // Step 9 (a): Deploy the proxy - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - return new Array(I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 9 (a): Deploy the proxy + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + return new Array(I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied); } async function setInPolymathRegistry(account_polymath) { - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); } - + async function registerGTM(account_polymath) { - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); } diff --git a/test/helpers/encodeCall.js b/test/helpers/encodeCall.js index 644c979a6..6a48f12a1 100644 --- a/test/helpers/encodeCall.js +++ b/test/helpers/encodeCall.js @@ -1,13 +1,14 @@ -const abi = require('ethereumjs-abi'); +const abi = require('ethereumjs-abi') export function encodeProxyCall(parametersType, values) { - const methodId = abi.methodID('initialize', parametersType).toString('hex'); + const methodId = abi.methodID("initialize", parametersType).toString('hex'); const params = abi.rawEncode(parametersType, values).toString('hex'); return '0x' + methodId + params; } + export function encodeModuleCall(parametersType, values) { - const methodId = abi.methodID('configure', parametersType).toString('hex'); + const methodId = abi.methodID("configure", parametersType).toString('hex'); const params = abi.rawEncode(parametersType, values).toString('hex'); return '0x' + methodId + params; -} +} \ No newline at end of file diff --git a/test/helpers/exceptions.js b/test/helpers/exceptions.js index 5c213a869..bdeda1472 100644 --- a/test/helpers/exceptions.js +++ b/test/helpers/exceptions.js @@ -10,12 +10,22 @@ async function tryCatch(promise, message) { try { assert( error.message.startsWith(PREFIX + message), - "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead" + "Expected an error starting with '" + + PREFIX + + message + + "' but got '" + + error.message + + "' instead" ); } catch (err) { assert( error.message.startsWith(PREFIX2 + message), - "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead" + "Expected an error starting with '" + + PREFIX + + message + + "' but got '" + + error.message + + "' instead" ); } } @@ -43,4 +53,4 @@ module.exports = { catchStaticStateChange: async function(promise) { await tryCatch(promise, 'static state change'); } -}; +}; \ No newline at end of file diff --git a/test/helpers/latestTime.js b/test/helpers/latestTime.js index bdc97053a..5e39a0355 100644 --- a/test/helpers/latestTime.js +++ b/test/helpers/latestTime.js @@ -1,4 +1,5 @@ // Returns the time of the last mined block in seconds -export default function latestTime() { - return web3.eth.getBlock('latest').timestamp; -} +export default function latestTime () { + return web3.eth.getBlock('latest').timestamp; + } + \ No newline at end of file diff --git a/test/helpers/signData.js b/test/helpers/signData.js index 738505df9..62b040719 100644 --- a/test/helpers/signData.js +++ b/test/helpers/signData.js @@ -4,18 +4,20 @@ const ethUtil = require('ethereumjs-util'); //this, _investor, _fromTime, _toTime, _validTo function signData(tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo, pk) { - let packedData = utils - .solidityKeccak256( - ['address', 'address', 'uint256', 'uint256', 'uint256', 'bool', 'uint256', 'uint256'], - [tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo] - ) - .slice(2); + let packedData = utils.solidityKeccak256( + [ "address", "address", "uint256", "uint256", "uint256", "bool", "uint256", "uint256" ], + [ tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo ] + ).slice(2); packedData = new Buffer(packedData, 'hex'); - packedData = Buffer.concat([new Buffer(`\x19Ethereum Signed Message:\n${packedData.length.toString()}`), packedData]); + packedData = Buffer.concat([ + new Buffer(`\x19Ethereum Signed Message:\n${packedData.length.toString()}`), + packedData]); packedData = web3.sha3(`0x${packedData.toString('hex')}`, { encoding: 'hex' }); - return ethUtil.ecsign(new Buffer(packedData.slice(2), 'hex'), new Buffer(pk, 'hex')); + return ethUtil.ecsign( + new Buffer(packedData.slice(2), 'hex'), + new Buffer(pk, 'hex')); } module.exports = { signData -}; +} diff --git a/test/helpers/testprivateKey.js b/test/helpers/testprivateKey.js index ae671f11d..16e464cd1 100644 --- a/test/helpers/testprivateKey.js +++ b/test/helpers/testprivateKey.js @@ -1,6 +1,6 @@ export const pk = { - account_0: '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200', - account_1: '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201' -}; + account_0 :'2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200', + account_1 :'2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201' +} export default { pk }; diff --git a/test/helpers/time.js b/test/helpers/time.js index 717bed9d0..37533c92b 100644 --- a/test/helpers/time.js +++ b/test/helpers/time.js @@ -2,73 +2,61 @@ // aren’t included within the original RPC specification. // See https://github.com/ethereumjs/testrpc#implemented-methods -function increaseTime(duration) { - const id = Date.now(); - - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync( - { +function increaseTime (duration) { + const id = Date.now(); + + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync({ jsonrpc: '2.0', method: 'evm_increaseTime', params: [duration], - id: id - }, - err1 => { + id: id, + }, err1 => { if (err1) return reject(err1); - - web3.currentProvider.sendAsync( - { - jsonrpc: '2.0', - method: 'evm_mine', - id: id + 1 - }, - (err2, res) => { - return err2 ? reject(err2) : resolve(res); - } - ); - } - ); - }); -} + + web3.currentProvider.sendAsync({ + jsonrpc: '2.0', + method: 'evm_mine', + id: id + 1, + }, (err2, res) => { + return err2 ? reject(err2) : resolve(res); + }); + }); + }); + } export default function takeSnapshot() { - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync( - { - jsonrpc: '2.0', - method: 'evm_snapshot', - params: [], - id: new Date().getTime() - }, - (err, result) => { - if (err) { - return reject(err); - } - - resolve(result.result); - } - ); - }); -} + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync({ + jsonrpc: '2.0', + method: 'evm_snapshot', + params: [], + id: new Date().getTime() + }, (err, result) => { + if (err) { + return reject(err); + } + + resolve(result.result); + }); + }); +}; function revertToSnapshot(snapShotId) { - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync( - { - jsonrpc: '2.0', - method: 'evm_revert', - params: [snapShotId], - id: new Date().getTime() - }, - err => { - if (err) { - return reject(err); - } - - resolve(); - } - ); - }); -} - -export { increaseTime, takeSnapshot, revertToSnapshot }; + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync({ + jsonrpc: '2.0', + method: 'evm_revert', + params: [snapShotId], + id: new Date().getTime() + }, (err) => { + if (err) { + return reject(err); + } + + resolve(); + }); + }); +}; + + export { increaseTime, takeSnapshot, revertToSnapshot }; \ No newline at end of file diff --git a/test/helpers/utils.js b/test/helpers/utils.js index 224a52c48..c1c900de1 100644 --- a/test/helpers/utils.js +++ b/test/helpers/utils.js @@ -1,73 +1,66 @@ /* global assert */ -var _ = require('lodash'); +var _ = require("lodash"); function isException(error) { - let strError = error.toString(); - return strError.includes('invalid opcode') || strError.includes('invalid JUMP') || strError.includes('revert'); + let strError = error.toString(); + return strError.includes('invalid opcode') || strError.includes('invalid JUMP') || strError.includes('revert'); } function ensureException(error) { - assert(isException(error), error.toString()); + assert(isException(error), error.toString()); } -async function timeDifference(timestamp1, timestamp2) { - var difference = timestamp1 - timestamp2; - return difference; +async function timeDifference(timestamp1,timestamp2) { + var difference = timestamp1 - timestamp2; + return difference; } function convertHex(hexx) { - var hex = hexx.toString(); //force conversion - var str = ''; - for (var i = 0; i < hex.length; i += 2) { - let char = String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - if (char != '\u0000') str += char; + var hex = hexx.toString(); //force conversion + var str = ''; + for (var i = 0; i < hex.length; i += 2) { + let char = String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + if (char != '\u0000') str += char; + } + return str; } - return str; -} -export { ensureException, timeDifference, convertHex }; +export { + ensureException, + timeDifference, + convertHex } export const duration = { - seconds: function(val) { - return val; - }, - minutes: function(val) { - return val * this.seconds(60); - }, - hours: function(val) { - return val * this.minutes(60); - }, - days: function(val) { - return val * this.hours(24); - }, - weeks: function(val) { - return val * this.days(7); - }, - years: function(val) { - return val * this.days(365); - } -}; + seconds: function (val) { return val; }, + minutes: function (val) { return val * this.seconds(60); }, + hours: function (val) { return val * this.minutes(60); }, + days: function (val) { return val * this.hours(24); }, + weeks: function (val) { return val * this.days(7); }, + years: function (val) { return val * this.days(365); }, + }; + /** - * Helper to wait for log emission. - * @param {Object} _event The event to wait for. - */ +* Helper to wait for log emission. +* @param {Object} _event The event to wait for. +*/ export function promisifyLogWatch(_event, _times) { - return new Promise((resolve, reject) => { - let i = 0; - _event.watch((error, log) => { - if (error !== null) reject(error); - i = i + 1; - console.log('Received event: ' + i + ' out of: ' + _times); - if (i == _times) { - _event.stopWatching(); - resolve(log); - } - }); - }); -} + return new Promise((resolve, reject) => { + let i = 0; + _event.watch((error, log) => { + if (error !== null) + reject(error); + i = i + 1; + console.log("Received event: " + i + " out of: " + _times); + if (i == _times) { + _event.stopWatching(); + resolve(log); + } + }); + }); + } -export function latestBlock() { - return web3.eth.getBlock('latest').number; -} + export function latestBlock () { + return web3.eth.getBlock('latest').number; + } \ No newline at end of file diff --git a/test/i_Issuance.js b/test/i_Issuance.js index cb81822fb..4cfe448d3 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -3,7 +3,7 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -21,189 +21,192 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port -contract('Issuance', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_fundsReceiver; - let account_delegate; - let blockNo; - let balanceOfReceiver; - let message = 'Transaction Should Fail!'; - const TM_Perm = 'WHITELIST'; - const delegateDetails = 'I am delegate'; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_CappedSTOFactory; - let I_MRProxied; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_CappedSTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = 'Demo Token'; - const symbol = 'DET'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // Capped STO details - //let startTime; // Start time will be 5000 seconds more than the latest time - //let endTime; // Add 30 days more - const cap = web3.utils.toWei('10000'); - const rate = 1000; - const fundRaiseType = [0]; - const cappedSTOSetupCost = web3.utils.toWei('20000', 'ether'); - const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[3]; - account_investor2 = accounts[2]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - token_owner = account_issuer; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); +contract('Issuance', accounts => { - // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_fundsReceiver; + let account_delegate; + let blockNo; + let balanceOfReceiver; + let message = "Transaction Should Fail!"; + const TM_Perm = "WHITELIST"; + const delegateDetails = "I am delegate" + // investor Details + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_CappedSTOFactory; + let I_MRProxied; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_CappedSTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = "Demo Token"; + const symbol = "DET"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // Capped STO details + //let startTime; // Start time will be 5000 seconds more than the latest time + //let endTime; // Add 30 days more + const cap = web3.utils.toWei("10000"); + const rate = 1000; + const fundRaiseType = [0]; + const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); + const maxCost = cappedSTOSetupCost; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[3]; + account_investor2 = accounts[2]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + token_owner = account_issuer; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - // STEP 5: Deploy the GeneralDelegateManagerFactory + // STEP 5: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - // STEP 6: Deploy the CappedSTOFactory + // STEP 6: Deploy the CappedSTOFactory - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CappedSTOFactory contract was not deployed' - ); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); - // Step 8: Deploy the STFactory contract + // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - // Step 9: Deploy the SecurityTokenRegistry contract + // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - // STEP 7: Register the Modules with the ModuleRegistry contract + // STEP 7: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -219,170 +222,202 @@ contract('Issuance', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Launch SecurityToken & STO on the behalf of the issuer', async () => { - describe('Create securityToken for the issuer by the polymath', async () => { - it('POLYMATH: Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_polymath); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); - let tx = await I_STRProxied.registerTicker(account_polymath, symbol, name, { from: account_polymath }); - assert.equal(tx.logs[0].args._owner, account_polymath); - assert.equal(tx.logs[0].args._ticker, symbol); - }); + }); - it('POLYMATH: Should generate the new security token with the same symbol as registered above', async () => { - console.log(name, symbol, tokenDetails, false); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_polymath }); + describe("Launch SecurityToken & STO on the behalf of the issuer", async() => { - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + describe("Create securityToken for the issuer by the polymath", async() => { - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + it("POLYMATH: Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_polymath); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); + let tx = await I_STRProxied.registerTicker(account_polymath, symbol, name, { from : account_polymath }); + assert.equal(tx.logs[0].args._owner, account_polymath); + assert.equal(tx.logs[0].args._ticker, symbol); + }); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + it("POLYMATH: Should generate the new security token with the same symbol as registered above", async () => { + console.log(name, symbol, tokenDetails, false); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_polymath }); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - it('POLYMATH: Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - it('POLYMATH: Should successfully attach the STO factory with the security token', async () => { - // STEP 4: Deploy the CappedSTOFactory + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: account_polymath }); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CappedSTOFactory contract was not deployed' - ); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - - let bytesSTO = encodeModuleCall(STOParameters, [ - latestTime() + duration.seconds(5000), - latestTime() + duration.days(30), - cap, - rate, - fundRaiseType, - account_fundsReceiver - ]); - - await I_PolyToken.getTokens(cappedSTOSetupCost, account_polymath); - await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: account_polymath }); - - const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: account_polymath }); - - assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), - 'CappedSTO', - 'CappedSTOFactory module was not added' - ); - I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); - }); - }); + it("POLYMATH: Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - describe('Transfer Manager operations by the polymath_account', async () => { - it('Should modify the whitelist', async () => { - fromTime = latestTime(); - toTime = latestTime() + duration.days(15); - expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime + duration.days(70), - toTime + duration.days(90), - expiryTime + duration.days(50), - true, - { - from: account_polymath - } - ); - assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); - }); - - it('Should add the delegate with permission', async () => { - //First attach a permission manager to the token - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '', 0, 0, { from: account_polymath }); - let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); - I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath }); - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { - from: account_polymath - }); - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); - }); + }); - it('POLYMATH: Should change the ownership of the SecurityToken', async () => { - await I_SecurityToken.transferOwnership(token_owner, { from: account_polymath }); + it("POLYMATH: Should successfully attach the STO factory with the security token", async () => { + // STEP 4: Deploy the CappedSTOFactory - assert.equal(await I_SecurityToken.owner.call(), token_owner); - }); - }); + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: account_polymath }); - describe('Operations on the STO', async () => { - it('Should Buy the tokens', async () => { - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - blockNo = latestBlock(); - // Jump time - await increaseTime(5000); - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO.address, - gas: 6100000, - value: web3.utils.toWei('1', 'ether') - }); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); - assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - assert.equal(await I_CappedSTO.investorCount.call(), 1); + let bytesSTO = encodeModuleCall(STOParameters, [(latestTime() + duration.seconds(5000)), (latestTime() + duration.days(30)), cap, rate, fundRaiseType, account_fundsReceiver]); - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - }); + await I_PolyToken.getTokens(cappedSTOSetupCost, account_polymath); + await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: account_polymath}); - it('Verification of the event Token Purchase', async () => { - const log = await promisifyLogWatch(I_CappedSTO.TokenPurchase({ from: blockNo }), 1); - assert.equal(log.args.purchaser, account_investor1, 'Wrong address of the investor'); - assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000, 'Wrong No. token get dilivered'); - }); + const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: account_polymath }); - it('should add the investor into the whitelist by the delegate', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { - from: account_delegate, - gas: 7000000 + assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "CappedSTO", + "CappedSTOFactory module was not added" + ); + I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); + }); }); - assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); - }); - - it('Should buy the token', async () => { - await web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); - - assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2); - assert.equal(await I_CappedSTO.investorCount.call(), 2); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - }); + describe("Transfer Manager operations by the polymath_account", async() => { + it("Should modify the whitelist", async () => { + + fromTime = latestTime(); + toTime = latestTime() + duration.days(15); + expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + fromTime + duration.days(70), + toTime + duration.days(90), + expiryTime + duration.days(50), + true, + { + from: account_polymath + }); + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); + }); + + it("Should add the delegate with permission", async() => { + //First attach a permission manager to the token + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: account_polymath}); + let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); + I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); + // Add permission to the deletgate (A regesteration process) + await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath}); + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: account_polymath }); + + assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); + }); + + it("POLYMATH: Should change the ownership of the SecurityToken", async() => { + await I_SecurityToken.transferOwnership(token_owner, { from : account_polymath }); + + assert.equal(await I_SecurityToken.owner.call(), token_owner); + }); + }) + + describe("Operations on the STO", async() => { + it("Should Buy the tokens", async() => { + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + blockNo = latestBlock(); + // Jump time + await increaseTime(5000); + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO.address, + gas: 6100000, + value: web3.utils.toWei('1', 'ether') + }); + + assert.equal( + (await I_CappedSTO.getRaised.call(0)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1 + ); + + assert.equal(await I_CappedSTO.investorCount.call(), 1); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + }); + + it("Verification of the event Token Purchase", async() => { + const log = await promisifyLogWatch(I_CappedSTO.TokenPurchase({from: blockNo}), 1); + assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); + assert.equal( + (log.args.amount) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000, + "Wrong No. token get dilivered" + ); + }); + + it("should add the investor into the whitelist by the delegate", async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + { + from: account_delegate, + gas: 7000000 + }); + assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); + }); + + it("Should buy the token", async () => { + await web3.eth.sendTransaction({ + from: account_investor2, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }); + + assert.equal( + (await I_CappedSTO.getRaised.call(0)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 2 + ); + + assert.equal(await I_CappedSTO.investorCount.call(), 2); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + }) + }); }); - }); }); diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 5d23bca83..b61c44e67 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -24,217 +24,209 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('ManualApprovalTransferManager', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_investor5; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_ManualApprovalTransferManagerFactory; - let P_ManualApprovalTransferManagerFactory; - let P_ManualApprovalTransferManager; - let I_CountTransferManagerFactory; - let I_GeneralPermissionManager; - let I_ManualApprovalTransferManager; - let I_CountTransferManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_MRProxied; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_investor5 = accounts[5]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactoryFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // STEP 6: Deploy the ManualApprovalTransferManagerFactory - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - assert.notEqual( - I_ManualApprovalTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'ManualApprovalTransferManagerFactory contract was not deployed' - ); - - // STEP 7: Deploy the Paid ManualApprovalTransferManagerFactory - P_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new( - I_PolyToken.address, - web3.utils.toWei('500', 'ether'), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_ManualApprovalTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'ManualApprovalTransferManagerFactory contract was not deployed' - ); - - // STEP 8: Deploy the CountTransferManagerFactory - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_CountTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CountTransferManagerFactory contract was not deployed' - ); - - // Step 10: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - - // Step 11: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - // Step 12: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 13: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 9: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the ManualApprovalTransferManagerFactory - await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the ManualApprovalTransferManagerFactory - await I_MRProxied.registerModule(P_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); - - // (D) : Register the CountTransferManagerFactory - await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_investor5; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_ManualApprovalTransferManagerFactory; + let P_ManualApprovalTransferManagerFactory; + let P_ManualApprovalTransferManager; + let I_CountTransferManagerFactory; + let I_GeneralPermissionManager; + let I_ManualApprovalTransferManager; + let I_CountTransferManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_MRProxied; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_investor5 = accounts[5]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 5: Deploy the GeneralDelegateManagerFactoryFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 6: Deploy the ManualApprovalTransferManagerFactory + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_ManualApprovalTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ManualApprovalTransferManagerFactory contract was not deployed" + ); + + // STEP 7: Deploy the Paid ManualApprovalTransferManagerFactory + P_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); + assert.notEqual( + P_ManualApprovalTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ManualApprovalTransferManagerFactory contract was not deployed" + ); + + // STEP 8: Deploy the CountTransferManagerFactory + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_CountTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CountTransferManagerFactory contract was not deployed" + ); + + // Step 10: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 11: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 12: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 13: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); + + // STEP 9: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the ManualApprovalTransferManagerFactory + await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the ManualApprovalTransferManagerFactory + await I_MRProxied.registerModule(P_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); + + // (D) : Register the CountTransferManagerFactory + await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -250,389 +242,366 @@ contract('ManualApprovalTransferManager', accounts => { CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toUtf8(log.args._name), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - }); - - describe('Buy tokens using whitelist & manual approvals', async () => { - it('Should Buy the tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(5000); - - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('4', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('4', 'ether')); - }); - - it('Should Buy some more tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Should successfully attach the ManualApprovalTransferManager with the security token', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); - await catchRevert( - I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, '0x', web3.utils.toWei('500', 'ether'), 0, { - from: token_owner - }) - ); - }); - - it('Should successfully attach the General permission manager factory with the security token', async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); - const tx = await I_SecurityToken.addModule( - P_ManualApprovalTransferManagerFactory.address, - '0x', - web3.utils.toWei('500', 'ether'), - 0, - { from: token_owner } - ); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), - 'ManualApprovalTransferManager', - 'ManualApprovalTransferManagerFactory module was not added' - ); - P_ManualApprovalTransferManagerFactory = ManualApprovalTransferManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); - }); - - it('Should successfully attach the ManualApprovalTransferManager with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, '', 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); - assert.equal( - web3.utils.toUtf8(tx.logs[2].args._name), - 'ManualApprovalTransferManager', - 'ManualApprovalTransferManager module was not added' - ); - I_ManualApprovalTransferManager = ManualApprovalTransferManager.at(tx.logs[2].args._module); - }); - //function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { - it('Cannot call verifyTransfer on the TM directly if _isTransfer == true', async () => { - await catchRevert( - I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { - from: token_owner - }) - ); - }); - - it('Can call verifyTransfer on the TM directly if _isTransfer == false', async () => { - await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), false, { - from: token_owner - }); - }); - - it('Add a new token holder', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Should still be able to transfer between existing token holders', async () => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('5', 'ether')); - }); - - it('Should fail to add a manual approval because invalid _from address', async () => { - await catchRevert( - I_ManualApprovalTransferManager.addManualApproval( - '', - account_investor4, - web3.utils.toWei('2', 'ether'), - latestTime() + duration.days(1), - { from: token_owner } - ) - ); - }); - - it('Should fail to add a manual approval because invalid _to address', async () => { - await catchRevert( - I_ManualApprovalTransferManager.addManualApproval( - account_investor1, - '', - web3.utils.toWei('2', 'ether'), - latestTime() + duration.days(1), - { from: token_owner } - ) - ); - }); - - it('Should fail to add a manual approval because invalid expiry time', async () => { - await catchRevert( - I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { - from: token_owner - }) - ); - }); - - it('Add a manual approval for a 4th investor', async () => { - await I_ManualApprovalTransferManager.addManualApproval( - account_investor1, - account_investor4, - web3.utils.toWei('2', 'ether'), - latestTime() + duration.days(1), - { from: token_owner } - ); - }); - - it('Should fail to revoke manual approval because invalid _from address', async () => { - await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval('', account_investor4, { from: token_owner })); }); - it('Should fail to revoke manual approval because invalid _to address', async () => { - await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, '', { from: token_owner })); - }); - - it('Should revoke manual approval', async () => { - let tx = await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, account_investor4, { from: token_owner }); - assert.equal(tx.logs[0].args._from, account_investor1); - assert.equal(tx.logs[0].args._to, account_investor4); - assert.equal(tx.logs[0].args._addedBy, token_owner); - await I_ManualApprovalTransferManager.addManualApproval( - account_investor1, - account_investor4, - web3.utils.toWei('2', 'ether'), - latestTime() + duration.days(1), - { from: token_owner } - ); - }); - - it('Use 50% of manual approval for transfer', async () => { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor4)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - - it('Check verifyTransfer without actually transferring', async () => { - let verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); - console.log(JSON.stringify(verified)); - assert.equal(verified, true); - - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('2', 'ether')); - assert.equal(verified, false); - - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); - assert.equal(verified, true); - }); - - it('Use remaining 50% of manual approval for transfer', async () => { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor4)).toNumber(), web3.utils.toWei('2', 'ether')); - }); - - it('Check further transfers fail', async () => { - await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - - //Check that other transfers are still valid - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - }); - - it('Should fail to add a manual block because invalid _from address', async () => { - await catchRevert( - I_ManualApprovalTransferManager.addManualBlocking('', account_investor2, latestTime() + duration.days(1), { from: token_owner }) - ); - }); + describe("Generate the SecurityToken", async() => { - it('Should fail to add a manual block because invalid _to address', async () => { - await catchRevert( - I_ManualApprovalTransferManager.addManualBlocking(account_investor1, '', latestTime() + duration.days(1), { from: token_owner }) - ); + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal(web3.utils.toUtf8(log.args._name), "GeneralTransferManager"); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + }); + + describe("Buy tokens using whitelist & manual approvals", async() => { + + it("Should Buy the tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('4', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('4', 'ether') + ); + }); + + it("Should Buy some more tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { + + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + await catchRevert(I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + }); + + it("Should successfully attach the General permission manager factory with the security token", async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "ManualApprovalTransferManager", + "ManualApprovalTransferManagerFactory module was not added" + ); + P_ManualApprovalTransferManagerFactory = ManualApprovalTransferManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + + it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); + assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManager module was not added"); + I_ManualApprovalTransferManager = ManualApprovalTransferManager.at(tx.logs[2].args._module); + }); +//function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { + it("Cannot call verifyTransfer on the TM directly if _isTransfer == true", async() => { + + await catchRevert(I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), true, { from: token_owner })); + + }); + + it("Can call verifyTransfer on the TM directly if _isTransfer == false", async() => { + await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), false, { from: token_owner }); + }); + + it("Add a new token holder", async() => { + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should still be able to transfer between existing token holders", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('5', 'ether') + ); + }); + + it("Should fail to add a manual approval because invalid _from address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.addManualApproval("", account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); + }); + + it("Should fail to add a manual approval because invalid _to address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, "", web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); + }); + + it("Should fail to add a manual approval because invalid expiry time", async() => { + + await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { from: token_owner })); + }); + + it("Add a manual approval for a 4th investor", async() => { + await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + }); + + it("Should fail to revoke manual approval because invalid _from address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner })); + }); + + it("Should fail to revoke manual approval because invalid _to address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, "", { from: token_owner })); + }); + + it("Should revoke manual approval", async() => { + let tx = await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, account_investor4, { from: token_owner }); + assert.equal(tx.logs[0].args._from, account_investor1); + assert.equal(tx.logs[0].args._to, account_investor4); + assert.equal(tx.logs[0].args._addedBy, token_owner); + await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + }); + + it("Use 50% of manual approval for transfer", async() => { + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor4)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Check verifyTransfer without actually transferring", async() => { + let verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); + console.log(JSON.stringify(verified)); + assert.equal(verified, true); + + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('2', 'ether')); + assert.equal(verified, false); + + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether')); + assert.equal(verified, true); + + }); + + it("Use remaining 50% of manual approval for transfer", async() => { + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor4)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Check further transfers fail", async() => { + + await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + + //Check that other transfers are still valid + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + + }); + + it("Should fail to add a manual block because invalid _from address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { from: token_owner })); + }); + + it("Should fail to add a manual block because invalid _to address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { from: token_owner })); + }); + + it("Should fail to add a manual block because invalid expiry time", async() => { + + await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner })); + }); + + it("Add a manual block for a 2nd investor", async() => { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); + }); + + it("Check manual block causes failure", async() => { + + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + + }); + + it("Should fail to revoke manual block because invalid _from address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking("0x0", account_investor2, { from: token_owner })); + }); + + it("Should fail to revoke manual block because invalid _to address", async() => { + + await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, "0x0", { from: token_owner })); + }); + + it("Revoke manual block and check transfer works", async() => { + await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, account_investor2, { from: token_owner }); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Check manual block ignored after expiry", async() => { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); + + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + await increaseTime(1 + (24 * 60 * 60)); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + }); + + it("Should successfully attach the CountTransferManager with the security token (count of 1)", async () => { + let bytesCountTM = web3.eth.abi.encodeFunctionCall({ + name: 'configure', + type: 'function', + inputs: [{ + type: 'uint256', + name: '_maxHolderCount' + } + ] + }, [1]); + + const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); + let name = web3.utils.toUtf8(tx.logs[2].args._name); + assert.equal(name, "CountTransferManager", "CountTransferManager module was not added"); + I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); + + }); + + it("Should get the permission list", async() => { + let perm = await I_ManualApprovalTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + }); + + // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { + // //Should fail initial transfer + // + // try { + // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + // } catch(error) { + // console.log(`Failed due to to count block`); + // ensureException(error); + // errorThrown = true; + // } + // //Add a manual approval - transfer should now work + // await I_ManualApprovalTransferManager.addManualApproval(account_investor2, account_investor5, web3.utils.toWei('1', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + // }); + + it("Should get the init function", async() => { + let byte = await I_ManualApprovalTransferManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); + }); + + }); + + describe("ManualApproval Transfer Manager Factory test cases", async() => { + + it("Should get the exact details of the factory", async() => { + assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(),0); + assert.equal(await I_ManualApprovalTransferManagerFactory.getType.call(),2); + let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); + assert.equal(name,"ManualApprovalTransferManager","Wrong Module added"); + let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); + assert.equal(desc,"Manage transfers using single approvals / blocking","Wrong Module added"); + let title = await I_ManualApprovalTransferManagerFactory.getTitle.call(); + assert.equal(title,"Manual Approval Transfer Manager","Wrong Module added"); + let inst = await I_ManualApprovalTransferManagerFactory.getInstructions.call(); + assert.equal(inst,"Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.","Wrong Module added"); + }); + + it("Should get the tags of the factory", async() => { + let tags = await I_ManualApprovalTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toUtf8(tags[0]), "ManualApproval"); + }); }); - it('Should fail to add a manual block because invalid expiry time', async () => { - await catchRevert( - I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner }) - ); - }); - - it('Add a manual block for a 2nd investor', async () => { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { - from: token_owner - }); - }); - - it('Check manual block causes failure', async () => { - await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - }); - - it('Should fail to revoke manual block because invalid _from address', async () => { - await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking('0x0', account_investor2, { from: token_owner })); - }); - - it('Should fail to revoke manual block because invalid _to address', async () => { - await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, '0x0', { from: token_owner })); - }); - - it('Revoke manual block and check transfer works', async () => { - await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, account_investor2, { from: token_owner }); - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); - }); - - it('Check manual block ignored after expiry', async () => { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { - from: token_owner - }); - - await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - await increaseTime(1 + 24 * 60 * 60); - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - }); - - it('Should successfully attach the CountTransferManager with the security token (count of 1)', async () => { - let bytesCountTM = web3.eth.abi.encodeFunctionCall( - { - name: 'configure', - type: 'function', - inputs: [ - { - type: 'uint256', - name: '_maxHolderCount' - } - ] - }, - [1] - ); - - const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); - let name = web3.utils.toUtf8(tx.logs[2].args._name); - assert.equal(name, 'CountTransferManager', 'CountTransferManager module was not added'); - I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); - }); - - it('Should get the permission list', async () => { - let perm = await I_ManualApprovalTransferManager.getPermissions.call(); - assert.equal(perm.length, 1); - }); - - // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { - // //Should fail initial transfer - // - // try { - // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - // } catch(error) { - // console.log(`Failed due to to count block`); - // ensureException(error); - // errorThrown = true; - // } - // //Add a manual approval - transfer should now work - // await I_ManualApprovalTransferManager.addManualApproval(account_investor2, account_investor5, web3.utils.toWei('1', 'ether'), latestTime() + duration.days(1), { from: token_owner }); - // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - // }); - - it('Should get the init function', async () => { - let byte = await I_ManualApprovalTransferManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); - }); - }); - - describe('ManualApproval Transfer Manager Factory test cases', async () => { - it('Should get the exact details of the factory', async () => { - assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(), 0); - assert.equal(await I_ManualApprovalTransferManagerFactory.getType.call(), 2); - let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); - assert.equal(name, 'ManualApprovalTransferManager', 'Wrong Module added'); - let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); - assert.equal(desc, 'Manage transfers using single approvals / blocking', 'Wrong Module added'); - let title = await I_ManualApprovalTransferManagerFactory.getTitle.call(); - assert.equal(title, 'Manual Approval Transfer Manager', 'Wrong Module added'); - let inst = await I_ManualApprovalTransferManagerFactory.getInstructions.call(); - assert.equal( - inst, - 'Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.', - 'Wrong Module added' - ); - }); - - it('Should get the tags of the factory', async () => { - let tags = await I_ManualApprovalTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toUtf8(tags[0]), 'ManualApproval'); - }); - }); }); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index 43997096f..b301081c5 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); @@ -25,172 +25,177 @@ const TestSTOFactory = artifacts.require('./TestSTOFactory.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + contract('ModuleRegistry', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_fundsReceiver; - let account_delegate; - let account_temp; - - let balanceOfReceiver; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - - let ID_snap; - let message = 'Transaction Should fail!'; - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_CappedSTOFactory1; - let I_CappedSTOFactory2; - let I_STFactory; - let I_MRProxied; - let I_SecurityToken; - let I_STRProxied; - let I_CappedSTO; - let I_PolyToken; - let I_MockFactory; - let I_TestSTOFactory; - let I_DummySTOFactory; - let I_PolymathRegistry; - let I_SecurityToken2; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = 'Demo Token'; - const symbol = 'det'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // delagate details - const delegateDetails = 'I am delegate ..'; - const TM_Perm = 'FLAGS'; - - // Capped STO details - let startTime; - let endTime; - const cap = web3.utils.toWei('10000'); - const rate = 1000; - const fundRaiseType = [0]; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[9]; - account_investor2 = accounts[6]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - account_temp = accounts[8]; - token_owner = account_issuer; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_ModuleRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'ModuleRegistry contract was not deployed' - ); - - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - let tx = await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - assert.notEqual( - I_FeatureRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'FeatureRegistry contract was not deployed' - ); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // Printing all the contract addresses - console.log(` + + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_fundsReceiver; + let account_delegate; + let account_temp; + + let balanceOfReceiver; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + + let ID_snap; + let message = "Transaction Should fail!"; + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_CappedSTOFactory1; + let I_CappedSTOFactory2; + let I_STFactory; + let I_MRProxied; + let I_SecurityToken; + let I_STRProxied; + let I_CappedSTO; + let I_PolyToken; + let I_MockFactory; + let I_TestSTOFactory; + let I_DummySTOFactory; + let I_PolymathRegistry; + let I_SecurityToken2; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = "Demo Token"; + const symbol = "det"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // delagate details + const delegateDetails = "I am delegate .."; + const TM_Perm = 'FLAGS'; + + // Capped STO details + let startTime; + let endTime; + const cap = web3.utils.toWei("10000"); + const rate = 1000; + const fundRaiseType = [0]; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256','uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[9]; + account_investor2 = accounts[6]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + account_temp = accounts[8]; + token_owner = account_issuer; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + + assert.notEqual( + I_ModuleRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ModuleRegistry contract was not deployed", + ); + + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + let tx = await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 9: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 10: update the registries addresses from the PolymathRegistry contract + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -203,350 +208,380 @@ contract('ModuleRegistry', accounts => { GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Test cases for the ModuleRegistry', async () => { - describe('Test case for the upgradeFromregistry', async () => { - it('Should successfully update the registry contract address -- failed because of bad owner', async () => { - await catchRevert(I_MRProxied.updateFromRegistry({ from: account_temp })); - }); - - it('Should successfully update the registry contract addresses', async () => { - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - assert.equal( - await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('securityTokenRegistry')), - I_SecurityTokenRegistryProxy.address - ); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('featureRegistry')), I_FeatureRegistry.address); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('polyToken')), I_PolyToken.address); - }); }); - describe('Test the state variables', async () => { - it('Should be the right owner', async () => { - let _owner = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')); - assert.equal(_owner, account_polymath, 'Owner should be the correct'); - }); + describe("Test cases for the ModuleRegistry", async() => { - it('Should be the expected value of the paused and intialised variable', async () => { - let _paused = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); - assert.isFalse(_paused, 'Should be the false'); + describe("Test case for the upgradeFromregistry", async() => { - let _intialised = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('initialised')); - assert.isTrue(_intialised, 'Values should be the true'); - }); + it("Should successfully update the registry contract address -- failed because of bad owner", async() => { + + await catchRevert(I_MRProxied.updateFromRegistry({from: account_temp})); + }); - it('Should be the expected value of the polymath registry', async () => { - let _polymathRegistry = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('polymathRegistry')); - assert.equal(_polymathRegistry, I_PolymathRegistry.address, 'Should be the right value of the address of the polymath registry'); - }); - }); - - describe('Test cases for the registering the module', async () => { - it('Should fail to register the module -- when registerModule is paused', async () => { - await I_MRProxied.pause({ from: account_polymath }); + it("Should successfully update the registry contract addresses", async() => { + await I_MRProxied.updateFromRegistry({from: account_polymath}); + assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("securityTokenRegistry")), I_SecurityTokenRegistryProxy.address); + assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("featureRegistry")), I_FeatureRegistry.address); + assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")), I_PolyToken.address); + }); - await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_delegate })); - await I_MRProxied.unpause({ from: account_polymath }); - }); - - it('Should register the module with the Module Registry', async () => { - let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, 'Should be the same address'); - assert.equal(tx.logs[0].args._owner, account_polymath, 'Should be the right owner'); + }); - let _list = await I_MRProxied.getModulesByType(transferManagerKey); - assert.equal(_list.length, 1, 'Length should be 1'); - assert.equal(_list[0], I_GeneralTransferManagerFactory.address); + describe("Test the state variables", async() => { - let _reputation = await I_MRProxied.getReputationByFactory(I_GeneralTransferManagerFactory.address); - assert.equal(_reputation.length, 0); - }); + it("Should be the right owner", async() => { + let _owner = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')); + assert.equal(_owner, account_polymath, "Owner should be the correct"); + }) - it('Should fail the register the module -- Already registered module', async () => { - await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath })); - }); + it("Should be the expected value of the paused and intialised variable", async() => { + let _paused = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); + assert.isFalse(_paused, "Should be the false"); - it('Should fail in registering the module-- type = 0', async () => { - I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + let _intialised = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("initialised")); + assert.isTrue(_intialised, "Values should be the true"); + }) - await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); - }); - }); + it("Should be the expected value of the polymath registry", async() => { + let _polymathRegistry = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry")); + assert.equal(_polymathRegistry, I_PolymathRegistry.address, "Should be the right value of the address of the polymath registry"); + }); + }); - describe('Test case for verifyModule', async () => { - it('Should fail in calling the verify module. Because msg.sender should be account_polymath', async () => { - await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); - }); - - it('Should successfully verify the module -- true', async () => { - let tx = await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, 'Failed in verifying the module'); - assert.equal(tx.logs[0].args._verified, true, 'Failed in verifying the module'); - }); - - it('Should successfully verify the module -- false', async () => { - I_CappedSTOFactory1 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - await I_MRProxied.registerModule(I_CappedSTOFactory1.address, { from: account_polymath }); - let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory1.address, false, { from: account_polymath }); - assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory1.address, 'Failed in verifying the module'); - assert.equal(tx.logs[0].args._verified, false, 'Failed in verifying the module'); - }); - - it('Should fail in verifying the module. Because the module is not registered', async () => { - await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); - }); - }); + describe("Test cases for the registering the module", async() => { + + it("Should fail to register the module -- when registerModule is paused", async() => { + await I_MRProxied.pause({from: account_polymath}); + + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_delegate})); + await I_MRProxied.unpause({from: account_polymath}); + }) + + it("Should register the module with the Module Registry", async() => { + let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath}); + assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, "Should be the same address"); + assert.equal(tx.logs[0].args._owner, account_polymath, "Should be the right owner"); + + let _list = await I_MRProxied.getModulesByType(transferManagerKey); + assert.equal(_list.length, 1, "Length should be 1"); + assert.equal(_list[0], I_GeneralTransferManagerFactory.address); + + let _reputation = await I_MRProxied.getReputationByFactory(I_GeneralTransferManagerFactory.address); + assert.equal(_reputation.length, 0); + }); + + it("Should fail the register the module -- Already registered module", async() => { + + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath})); + }) + + it("Should fail in registering the module-- type = 0", async() => { + I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); + + await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); + }); + }); - describe('Test cases for the useModule function of the module registry', async () => { - it('Deploy the securityToken', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('500'), account_issuer); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: account_issuer }); - await I_STRProxied.registerTicker(account_issuer, symbol, name, { from: account_issuer }); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, { from: account_issuer }); - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase()); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - }); + describe("Test case for verifyModule", async() => { + + it("Should fail in calling the verify module. Because msg.sender should be account_polymath", async () => { + + await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); + }); + + it("Should successfully verify the module -- true", async() => { + let tx = await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + assert.equal( + tx.logs[0].args._moduleFactory, + I_GeneralTransferManagerFactory.address, + "Failed in verifying the module" + ); + assert.equal( + tx.logs[0].args._verified, + true, + "Failed in verifying the module" + ); + }); + + it("Should successfully verify the module -- false", async() => { + I_CappedSTOFactory1 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); + await I_MRProxied.registerModule(I_CappedSTOFactory1.address, {from: account_polymath}); + let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory1.address, false, { from: account_polymath }); + assert.equal( + tx.logs[0].args._moduleFactory, + I_CappedSTOFactory1.address, + "Failed in verifying the module" + ); + assert.equal( + tx.logs[0].args._verified, + false, + "Failed in verifying the module" + ); + }); + + it("Should fail in verifying the module. Because the module is not registered", async() => { + + await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); + }); + }) + + describe("Test cases for the useModule function of the module registry", async() => { + + it("Deploy the securityToken", async() => { + await I_PolyToken.getTokens(web3.utils.toWei("500"), account_issuer); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), {from: account_issuer}); + await I_STRProxied.registerTicker(account_issuer, symbol, name, {from: account_issuer}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, {from: account_issuer}); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase()); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + }); + + it("Should fail in adding module. Because module is un-verified", async() => { + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner})); + }); + + it("Should fail to register module because custom modules not allowed", async() => { + I_CappedSTOFactory2 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); + + assert.notEqual( + I_CappedSTOFactory2.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); + + + + await catchRevert(I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner })); + + }); + + it("Should switch customModulesAllowed to true", async() => { + assert.equal(false, await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), "Custom modules should be dissabled by default."); + let tx = await I_FeatureRegistry.setFeatureStatus("customModulesAllowed", true, { from: account_polymath }); + assert.equal(true, await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), "Custom modules should be switched to true."); + }); + + it("Should successfully add module because custom modules switched on", async() => { + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); + tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner}); + + assert.equal(tx.logs[2].args._type, stoKey, "CappedSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "CappedSTO", + "CappedSTOFactory module was not added" + ); + let _reputation = await I_MRProxied.getReputationByFactory.call(I_CappedSTOFactory2.address); + assert.equal(_reputation.length, 1); + }); + + it("Should successfully add verified module", async() => { + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, {from: account_polymath}); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, {from: account_polymath}); + let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type, permissionManagerKey, "module doesn't get deployed"); + }); + + it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower", async() => { + I_TestSTOFactory = await TestSTOFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); + await I_MRProxied.registerModule(I_TestSTOFactory.address, {from: account_polymath}); + await I_MRProxied.verifyModule(I_TestSTOFactory.address, true, {from: account_polymath}); + // Taking the snapshot the revert the changes from here + let id = await takeSnapshot(); + await I_TestSTOFactory.changeSTVersionBounds("lowerBound", [0,1,0], {from: account_polymath}); + let _lstVersion = await I_TestSTOFactory.getLowerSTVersionBounds.call() + assert.equal(_lstVersion[2],0); + assert.equal(_lstVersion[1],1); + let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); + + await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); + await revertToSnapshot(id); + }) + + it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --upper", async() => { + await I_TestSTOFactory.changeSTVersionBounds("upperBound", [0,0,1], {from: account_polymath}); + let _ustVersion = await I_TestSTOFactory.getUpperSTVersionBounds.call() + assert.equal(_ustVersion[0],0); + assert.equal(_ustVersion[2],1); + await I_STRProxied.setProtocolVersion(I_STFactory.address, 1, 0, 1); + + // Generate the new securityToken + let newSymbol = "toro"; + await I_PolyToken.getTokens(web3.utils.toWei("500"), account_issuer); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), {from: account_issuer}); + await I_STRProxied.registerTicker(account_issuer, newSymbol, name, {from: account_issuer}); + let tx = await I_STRProxied.generateSecurityToken(name, newSymbol, tokenDetails, true, {from: account_issuer}); + assert.equal(tx.logs[1].args._ticker, newSymbol.toUpperCase()); + I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + + let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); + + await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); + }); - it('Should fail in adding module. Because module is un-verified', async () => { - startTime = latestTime() + duration.seconds(5000); - endTime = startTime + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + }); - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner })); - }); + describe("Test case for the getModulesByTypeAndToken()", async() => { + + it("Should get the list of available modules when the customModulesAllowed", async() => { + let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); + assert.equal(_list[0], I_CappedSTOFactory2.address); + }) + + it("Should get the list of available modules when the customModulesAllowed is not allowed", async() => { + await I_FeatureRegistry.setFeatureStatus("customModulesAllowed", false, { from: account_polymath }); + let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); + assert.equal(_list.length, 0); + }) + }) + + describe("Test cases for getters", async() => { + + it("Check getter - ", async() => { + console.log("getModulesByType:") + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getModulesByType.call(i); + console.log("Type: " + i + ":" + _list); + } + console.log("getModulesByTypeAndToken:") + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getModulesByTypeAndToken.call(i, I_SecurityToken.address); + console.log("Type: " + i + ":" + _list); + } + console.log("getTagsByType:") + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getTagsByType.call(i); + console.log("Type: " + i + ":" + _list[1]); + console.log("Type: " + i + ":" + _list[0].map(x => web3.utils.toAscii(x))); + } + console.log("getTagsByTypeAndToken:") + for (let i = 0; i < 5; i++) { + let _list = await I_MRProxied.getTagsByTypeAndToken.call(i, I_SecurityToken.address); + console.log("Type: " + i + ":" + _list[1]); + console.log("Type: " + i + ":" + _list[0].map(x => web3.utils.toAscii(x))); + } + }) - it('Should fail to register module because custom modules not allowed', async () => { - I_CappedSTOFactory2 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); + }); - assert.notEqual( - I_CappedSTOFactory2.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CappedSTOFactory contract was not deployed' - ); + describe("Test cases for removeModule()", async() => { - await catchRevert(I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner })); - }); + it("Should fail if msg.sender not curator or owner", async() => { + + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp })); + }); - it('Should switch customModulesAllowed to true', async () => { - assert.equal( - false, - await I_FeatureRegistry.getFeatureStatus.call('customModulesAllowed'), - 'Custom modules should be dissabled by default.' - ); - let tx = await I_FeatureRegistry.setFeatureStatus('customModulesAllowed', true, { from: account_polymath }); - assert.equal( - true, - await I_FeatureRegistry.getFeatureStatus.call('customModulesAllowed'), - 'Custom modules should be switched to true.' - ); - }); - - it('Should successfully add module because custom modules switched on', async () => { - startTime = latestTime() + duration.seconds(5000); - endTime = startTime + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); - tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner }); - - assert.equal(tx.logs[2].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'CappedSTO', - 'CappedSTOFactory module was not added' - ); - let _reputation = await I_MRProxied.getReputationByFactory.call(I_CappedSTOFactory2.address); - assert.equal(_reputation.length, 1); - }); + it("Should successfully remove module and delete data if msg.sender is curator", async() => { + let snap = await takeSnapshot(); - it('Should successfully add verified module', async () => { - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '', 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type, permissionManagerKey, "module doesn't get deployed"); - }); - - it('Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower', async () => { - I_TestSTOFactory = await TestSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - await I_MRProxied.registerModule(I_TestSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_TestSTOFactory.address, true, { from: account_polymath }); - // Taking the snapshot the revert the changes from here - let id = await takeSnapshot(); - await I_TestSTOFactory.changeSTVersionBounds('lowerBound', [0, 1, 0], { from: account_polymath }); - let _lstVersion = await I_TestSTOFactory.getLowerSTVersionBounds.call(); - assert.equal(_lstVersion[2], 0); - assert.equal(_lstVersion[1], 1); - let bytesData = encodeModuleCall( - ['uint256', 'uint256', 'uint256', 'string'], - [latestTime(), latestTime() + duration.days(1), cap, 'Test STO'] - ); + let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; + let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; - await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); - await revertToSnapshot(id); - }); - - it('Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --upper', async () => { - await I_TestSTOFactory.changeSTVersionBounds('upperBound', [0, 0, 1], { from: account_polymath }); - let _ustVersion = await I_TestSTOFactory.getUpperSTVersionBounds.call(); - assert.equal(_ustVersion[0], 0); - assert.equal(_ustVersion[2], 1); - await I_STRProxied.setProtocolVersion(I_STFactory.address, 1, 0, 1); - - // Generate the new securityToken - let newSymbol = 'toro'; - await I_PolyToken.getTokens(web3.utils.toWei('500'), account_issuer); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: account_issuer }); - await I_STRProxied.registerTicker(account_issuer, newSymbol, name, { from: account_issuer }); - let tx = await I_STRProxied.generateSecurityToken(name, newSymbol, tokenDetails, true, { from: account_issuer }); - assert.equal(tx.logs[1].args._ticker, newSymbol.toUpperCase()); - I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - let bytesData = encodeModuleCall( - ['uint256', 'uint256', 'uint256', 'string'], - [latestTime(), latestTime() + duration.days(1), cap, 'Test STO'] - ); + assert.equal(sto1,I_CappedSTOFactory1.address); + assert.equal(sto2,I_CappedSTOFactory2.address); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); - await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); - }); - }); + let tx = await I_MRProxied.removeModule(sto1, { from: account_polymath }); - describe('Test case for the getModulesByTypeAndToken()', async () => { - it('Should get the list of available modules when the customModulesAllowed', async () => { - let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); - assert.equal(_list[0], I_CappedSTOFactory2.address); - }); - - it('Should get the list of available modules when the customModulesAllowed is not allowed', async () => { - await I_FeatureRegistry.setFeatureStatus('customModulesAllowed', false, { from: account_polymath }); - let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); - assert.equal(_list.length, 0); - }); - }); + assert.equal(tx.logs[0].args._moduleFactory, sto1, "Event is not properly emitted for _moduleFactory"); + assert.equal(tx.logs[0].args._decisionMaker, account_polymath, "Event is not properly emitted for _decisionMaker"); - describe('Test cases for getters', async () => { - it('Check getter - ', async () => { - console.log('getModulesByType:'); - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getModulesByType.call(i); - console.log('Type: ' + i + ':' + _list); - } - console.log('getModulesByTypeAndToken:'); - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getModulesByTypeAndToken.call(i, I_SecurityToken.address); - console.log('Type: ' + i + ':' + _list); - } - console.log('getTagsByType:'); - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getTagsByType.call(i); - console.log('Type: ' + i + ':' + _list[1]); - console.log('Type: ' + i + ':' + _list[0].map(x => web3.utils.toAscii(x))); - } - console.log('getTagsByTypeAndToken:'); - for (let i = 0; i < 5; i++) { - let _list = await I_MRProxied.getTagsByTypeAndToken.call(i, I_SecurityToken.address); - console.log('Type: ' + i + ':' + _list[1]); - console.log('Type: ' + i + ':' + _list[0].map(x => web3.utils.toAscii(x))); - } - }); - }); + let sto2_end = (await I_MRProxied.getModulesByType.call(3))[1]; - describe('Test cases for removeModule()', async () => { - it('Should fail if msg.sender not curator or owner', async () => { - await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp })); - }); + // re-ordering + assert.equal(sto2_end,sto2); + // delete related data + assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto1)), 0); + assert.equal(await I_MRProxied.getReputationByFactory.call(sto1), 0); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); + assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto1)), false); - it('Should successfully remove module and delete data if msg.sender is curator', async () => { - let snap = await takeSnapshot(); + await revertToSnapshot(snap); + }); - let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; - let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; + it("Should successfully remove module and delete data if msg.sender is owner", async() => { + let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; + let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; - assert.equal(sto1, I_CappedSTOFactory1.address); - assert.equal(sto2, I_CappedSTOFactory2.address); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); + assert.equal(sto1,I_CappedSTOFactory1.address); + assert.equal(sto2,I_CappedSTOFactory2.address); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); - let tx = await I_MRProxied.removeModule(sto1, { from: account_polymath }); + let tx = await I_MRProxied.removeModule(sto2, { from: token_owner }); - assert.equal(tx.logs[0].args._moduleFactory, sto1, 'Event is not properly emitted for _moduleFactory'); - assert.equal(tx.logs[0].args._decisionMaker, account_polymath, 'Event is not properly emitted for _decisionMaker'); + assert.equal(tx.logs[0].args._moduleFactory, sto2, "Event is not properly emitted for _moduleFactory"); + assert.equal(tx.logs[0].args._decisionMaker, token_owner, "Event is not properly emitted for _decisionMaker"); - let sto2_end = (await I_MRProxied.getModulesByType.call(3))[1]; + let sto1_end = (await I_MRProxied.getModulesByType.call(3))[0]; - // re-ordering - assert.equal(sto2_end, sto2); - // delete related data - assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3('registry', sto1)), 0); - assert.equal(await I_MRProxied.getReputationByFactory.call(sto1), 0); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); - assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('verified', sto1)), false); + // re-ordering + assert.equal(sto1_end,sto1); + // delete related data + assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto2)), 0); + assert.equal(await I_MRProxied.getReputationByFactory.call(sto2), 0); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); + assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto2)), false); + }); - await revertToSnapshot(snap); - }); + it("Should fail if module already removed", async() => { + + await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath })); + }); - it('Should successfully remove module and delete data if msg.sender is owner', async () => { - let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; - let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; + }); - assert.equal(sto1, I_CappedSTOFactory1.address); - assert.equal(sto2, I_CappedSTOFactory2.address); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); + describe("Test cases for IRegistry functionality", async() => { - let tx = await I_MRProxied.removeModule(sto2, { from: token_owner }); + describe("Test cases for reclaiming funds", async() => { - assert.equal(tx.logs[0].args._moduleFactory, sto2, 'Event is not properly emitted for _moduleFactory'); - assert.equal(tx.logs[0].args._decisionMaker, token_owner, 'Event is not properly emitted for _decisionMaker'); + it("Should successfully reclaim POLY tokens", async() => { + await I_PolyToken.getTokens(web3.utils.toWei("1"), I_MRProxied.address); + let bal1 = await I_PolyToken.balanceOf.call(account_polymath); + await I_MRProxied.reclaimERC20(I_PolyToken.address); + let bal2 = await I_PolyToken.balanceOf.call(account_polymath); + assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); + }); - let sto1_end = (await I_MRProxied.getModulesByType.call(3))[0]; + }); - // re-ordering - assert.equal(sto1_end, sto1); - // delete related data - assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3('registry', sto2)), 0); - assert.equal(await I_MRProxied.getReputationByFactory.call(sto2), 0); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); - assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('verified', sto2)), false); - }); + describe("Test cases for pausing the contract", async() => { - it('Should fail if module already removed', async () => { - await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath })); - }); - }); + it("Should fail to pause if msg.sender is not owner", async() => { + + await catchRevert(I_MRProxied.pause({ from: account_temp })); + }); - describe('Test cases for IRegistry functionality', async () => { - describe('Test cases for reclaiming funds', async () => { - it('Should successfully reclaim POLY tokens', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('1'), I_MRProxied.address); - let bal1 = await I_PolyToken.balanceOf.call(account_polymath); - await I_MRProxied.reclaimERC20(I_PolyToken.address); - let bal2 = await I_PolyToken.balanceOf.call(account_polymath); - assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); - }); - }); + it("Should successfully pause the contract", async() => { + await I_MRProxied.pause({ from: account_polymath }); + let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); + assert.isOk(status); + }); - describe('Test cases for pausing the contract', async () => { - it('Should fail to pause if msg.sender is not owner', async () => { - await catchRevert(I_MRProxied.pause({ from: account_temp })); - }); + it("Should fail to unpause if msg.sender is not owner", async() => { + + await catchRevert(I_MRProxied.unpause({ from: account_temp })); + }); - it('Should successfully pause the contract', async () => { - await I_MRProxied.pause({ from: account_polymath }); - let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); - assert.isOk(status); - }); + it("Should successfully unpause the contract", async() => { + await I_MRProxied.unpause({ from: account_polymath }); + let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); + assert.isNotOk(status); + }); - it('Should fail to unpause if msg.sender is not owner', async () => { - await catchRevert(I_MRProxied.unpause({ from: account_temp })); }); - it('Should successfully unpause the contract', async () => { - await I_MRProxied.unpause({ from: account_polymath }); - let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); - assert.isNotOk(status); - }); - }); }); - }); + }); + }); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index 0e34f0f29..76c623b03 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -13,383 +13,378 @@ const SecurityToken = artifacts.require('./SecurityToken.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('PercentageTransferManager', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let P_PercentageTransferManagerFactory; - let I_SecurityTokenRegistryProxy; - let P_PercentageTransferManager; - let I_GeneralTransferManagerFactory; - let I_PercentageTransferManagerFactory; - let I_GeneralPermissionManager; - let I_PercentageTransferManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STRProxied; - let I_MRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - var I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // PercentageTransferManager details - const holderPercentage = 70 * 10 ** 16; // Maximum number of token holders - - let bytesSTO = web3.eth.abi.encodeFunctionCall( - { - name: 'configure', - type: 'function', - inputs: [ - { - type: 'uint256', - name: '_maxHolderPercentage' + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let P_PercentageTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let P_PercentageTransferManager; + let I_GeneralTransferManagerFactory; + let I_PercentageTransferManagerFactory; + let I_GeneralPermissionManager; + let I_PercentageTransferManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_MRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + var I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // PercentageTransferManager details + const holderPercentage = 70 * 10**16; // Maximum number of token holders + + let bytesSTO = web3.eth.abi.encodeFunctionCall({ + name: 'configure', + type: 'function', + inputs: [{ + type: 'uint256', + name: '_maxHolderPercentage' } - ] - }, - [holderPercentage] - ); - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[7]; - account_investor2 = accounts[8]; - account_investor3 = accounts[9]; - - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [ - I_PolymathRegistry, - I_PolyToken, - I_FeatureRegistry, - I_ModuleRegistry, - I_ModuleRegistryProxy, - I_MRProxied, - I_GeneralTransferManagerFactory, - I_STFactory, - I_SecurityTokenRegistry, - I_SecurityTokenRegistryProxy, - I_STRProxied - ] = instances; - - // STEP 4(b): Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // STEP 4(c): Deploy the PercentageTransferManager - I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - assert.notEqual( - I_PercentageTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'PercentageTransferManagerFactory contract was not deployed' - ); - - // STEP 4(d): Deploy the PercentageTransferManager - P_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new( - I_PolyToken.address, - web3.utils.toWei('500', 'ether'), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_PercentageTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'PercentageTransferManagerFactory contract was not deployed' - ); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the PercentageTransferManagerFactory - await I_MRProxied.registerModule(I_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PercentageTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid PercentageTransferManagerFactory - await I_MRProxied.registerModule(P_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_PercentageTransferManagerFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} - FeatureRegistry: ${I_FeatureRegistry.address} + ] + }, [holderPercentage]); - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; - PercentageTransferManagerFactory: ${I_PercentageTransferManagerFactory.address} - ----------------------------------------------------------------------------- - `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); + token_owner = account_issuer; - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + account_investor1 = accounts[7]; + account_investor2 = accounts[8]; + account_investor3 = accounts[9]; - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + let instances = await setUpPolymathNetwork(account_polymath, token_owner); - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, + I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + // STEP 4(b): Deploy the GeneralDelegateManagerFactory - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - }); - - describe('Buy tokens using on-chain whitelist', async () => { - it('Should Buy the tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - } - ); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - // Jump time - await increaseTime(5000); + // STEP 4(c): Deploy the PercentageTransferManager + I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_PercentageTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "PercentageTransferManagerFactory contract was not deployed" + ); - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + // STEP 4(d): Deploy the PercentageTransferManager + P_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); + assert.notEqual( + P_PercentageTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "PercentageTransferManagerFactory contract was not deployed" + ); - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); - }); - it('Should Buy some more tokens', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - } - ); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); + // (C) : Register the PercentageTransferManagerFactory + await I_MRProxied.registerModule(I_PercentageTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_PercentageTransferManagerFactory.address, true, { from: account_polymath }); - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + // (C) : Register the Paid PercentageTransferManagerFactory + await I_MRProxied.registerModule(P_PercentageTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_PercentageTransferManagerFactory.address, true, { from: account_polymath }); - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('1', 'ether')); - }); + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} - it('Should successfully attach the PercentageTransferManagerr factory with the security token', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('500', 'ether'), token_owner); - await catchRevert( - I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei('500', 'ether'), 0, { - from: token_owner - }) - ); - }); + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - it('Should successfully attach the PercentageTransferManager factory with the security token', async () => { - let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei('500', 'ether'), { from: token_owner }); - const tx = await I_SecurityToken.addModule( - P_PercentageTransferManagerFactory.address, - bytesSTO, - web3.utils.toWei('500', 'ether'), - 0, - { from: token_owner } - ); - assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ''), - 'PercentageTransferManager', - 'PercentageTransferManagerFactory module was not added' - ); - P_PercentageTransferManager = PercentageTransferManager.at(tx.logs[3].args._module); - await revertToSnapshot(snapId); + PercentageTransferManagerFactory: ${I_PercentageTransferManagerFactory.address} + ----------------------------------------------------------------------------- + `); }); - it('Should successfully attach the PercentageTransferManager with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'PercentageTransferManager', - 'PercentageTransferManager module was not added' - ); - I_PercentageTransferManager = PercentageTransferManager.at(tx.logs[2].args._module); - }); + describe("Generate the SecurityToken", async() => { - it('Add a new token holder', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - latestTime(), - latestTime(), - latestTime() + duration.days(10), - true, - { - from: account_issuer, - gas: 6000000 - } - ); + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), 'Failed in adding the investor in whitelist'); + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('1', 'ether')); - }); + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - it('Should pause the tranfers at transferManager level', async () => { - let tx = await I_PercentageTransferManager.pause({ from: token_owner }); - }); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - it('Should still be able to transfer between existing token holders up to limit', async () => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('2', 'ether')); - }); + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - it('Should unpause the tranfers at transferManager level', async () => { - await I_PercentageTransferManager.unpause({ from: token_owner }); - }); + }); - it('Should not be able to transfer between existing token holders over limit', async () => { - await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 })); }); - it('Modify holder percentage to 100', async () => { - // Add the Investor in to the whitelist - // Mint some tokens - await I_PercentageTransferManager.changeHolderPercentage(100 * 10 ** 16, { from: token_owner }); - - assert.equal((await I_PercentageTransferManager.maxHolderPercentage()).toNumber(), 100 * 10 ** 16); - }); + describe("Buy tokens using on-chain whitelist", async() => { + + it("Should Buy the tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should Buy some more tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should successfully attach the PercentageTransferManagerr factory with the security token", async () => { + + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + await catchRevert(I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + }); + + it("Should successfully attach the PercentageTransferManager factory with the security token", async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._type.toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "PercentageTransferManager", + "PercentageTransferManagerFactory module was not added" + ); + P_PercentageTransferManager = PercentageTransferManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it("Should successfully attach the PercentageTransferManager with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "PercentageTransferManager", + "PercentageTransferManager module was not added" + ); + I_PercentageTransferManager = PercentageTransferManager.at(tx.logs[2].args._module); + }); + + it("Add a new token holder", async() => { + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Should pause the tranfers at transferManager level", async() => { + let tx = await I_PercentageTransferManager.pause({from: token_owner}); + }); + + it("Should still be able to transfer between existing token holders up to limit", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Should unpause the tranfers at transferManager level", async() => { + await I_PercentageTransferManager.unpause({from: token_owner}); + }) - it('Should be able to transfer between existing token holders up to limit', async () => { - await I_PercentageTransferManager.modifyWhitelist(account_investor3, false, { from: token_owner }); - await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); - }); + it("Should not be able to transfer between existing token holders over limit", async() => { + + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 })); + }); + + it("Modify holder percentage to 100", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_PercentageTransferManager.changeHolderPercentage(100 * 10**16, { from: token_owner }); + + assert.equal( + (await I_PercentageTransferManager.maxHolderPercentage()).toNumber(), + 100 * 10**16 + ); + }); + + it("Should be able to transfer between existing token holders up to limit", async() => { + await I_PercentageTransferManager.modifyWhitelist(account_investor3, false, { from: token_owner }); + await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); + }); + + it("Should be able to whitelist address and then transfer regardless of holders", async() => { + await I_PercentageTransferManager.changeHolderPercentage(30 * 10**16, { from: token_owner }); + await I_PercentageTransferManager.modifyWhitelist(account_investor1, true, { from: token_owner }); + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor3 }); + }); + + it("Should get the permission", async() => { + let perm = await I_PercentageTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + }); - it('Should be able to whitelist address and then transfer regardless of holders', async () => { - await I_PercentageTransferManager.changeHolderPercentage(30 * 10 ** 16, { from: token_owner }); - await I_PercentageTransferManager.modifyWhitelist(account_investor1, true, { from: token_owner }); - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor3 }); }); - it('Should get the permission', async () => { - let perm = await I_PercentageTransferManager.getPermissions.call(); - assert.equal(perm.length, 1); - }); - }); - - describe('Percentage Transfer Manager Factory test cases', async () => { - it('Should get the exact details of the factory', async () => { - assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(), 0); - assert.equal(await I_PercentageTransferManagerFactory.getType.call(), 2); - assert.equal( - web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()).replace(/\u0000/g, ''), - 'PercentageTransferManager', - 'Wrong Module added' - ); - assert.equal( - await I_PercentageTransferManagerFactory.getDescription.call(), - 'Restrict the number of investors', - 'Wrong Module added' - ); - assert.equal(await I_PercentageTransferManagerFactory.getTitle.call(), 'Percentage Transfer Manager', 'Wrong Module added'); - assert.equal( - await I_PercentageTransferManagerFactory.getInstructions.call(), - 'Allows an issuer to restrict the total number of non-zero token holders', - 'Wrong Module added' - ); + describe("Percentage Transfer Manager Factory test cases", async() => { + + it("Should get the exact details of the factory", async() => { + assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(),0); + assert.equal(await I_PercentageTransferManagerFactory.getType.call(),2); + assert.equal(web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()) + .replace(/\u0000/g, ''), + "PercentageTransferManager", + "Wrong Module added"); + assert.equal(await I_PercentageTransferManagerFactory.getDescription.call(), + "Restrict the number of investors", + "Wrong Module added"); + assert.equal(await I_PercentageTransferManagerFactory.getTitle.call(), + "Percentage Transfer Manager", + "Wrong Module added"); + assert.equal(await I_PercentageTransferManagerFactory.getInstructions.call(), + "Allows an issuer to restrict the total number of non-zero token holders", + "Wrong Module added"); + + }); + + it("Should get the tags of the factory", async() => { + let tags = await I_PercentageTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "Percentage"); + }); }); - it('Should get the tags of the factory', async () => { - let tags = await I_PercentageTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Percentage'); - }); - }); }); diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index 7e03917e6..edda686f3 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const PreSaleSTOFactory = artifacts.require('./PreSaleSTOFactory.sol'); const PreSaleSTO = artifacts.require('./PreSaleSTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -22,184 +22,184 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('PreSaleSTO', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_investor3; - let account_fundsReceiver; - - let balanceOfReceiver; - let message = 'Transaction Should Fail!'; - // investor Details - let fromTime; - let toTime; - let expiryTime; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_PreSaleSTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_MRProxied; - let I_STRProxied; - let I_PreSaleSTO; - let I_PolyToken; - let I_PolymathRegistry; - - // SecurityToken Details for funds raise Type ETH - const name = 'Team'; - const symbol = 'SAP'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - // SecurityToken Details for funds raise Type POLY - const P_name = 'Team Poly'; - const P_symbol = 'PAS'; - const P_tokenDetails = 'This is equity type of issuance'; - const P_decimals = 18; - - // Module key - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - let endTime; - const STOParameters = ['uint256']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[4]; - account_investor2 = accounts[3]; - account_investor3 = accounts[5]; - account_fundsReceiver = accounts[2]; - token_owner = account_issuer; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // STEP 4: Deploy the PreSaleSTOFactory + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_investor3; + let account_fundsReceiver; + + let balanceOfReceiver; + let message = "Transaction Should Fail!"; + // investor Details + let fromTime; + let toTime; + let expiryTime; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_PreSaleSTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_MRProxied; + let I_STRProxied; + let I_PreSaleSTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details for funds raise Type ETH + const name = "Team"; + const symbol = "SAP"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + + // SecurityToken Details for funds raise Type POLY + const P_name = "Team Poly"; + const P_symbol = "PAS"; + const P_tokenDetails = "This is equity type of issuance"; + const P_decimals = 18; + + // Module key + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + let endTime; + const STOParameters = ['uint256']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[4]; + account_investor2 = accounts[3]; + account_investor3 = accounts[5]; + account_fundsReceiver = accounts[2]; + token_owner = account_issuer; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 3: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 4: Deploy the PreSaleSTOFactory + + I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); + + assert.notEqual( + I_PreSaleSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "PreSaleSTOFactory contract was not deployed" + ); + + // Step 8: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 9: Deploy the SecurityTokenRegistry contract - I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - assert.notEqual( - I_PreSaleSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'PreSaleSTOFactory contract was not deployed' - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - // Step 8: Deploy the STFactory contract + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + // STEP 5: Register the Modules with the ModuleRegistry contract - // Step 9: Deploy the SecurityTokenRegistry contract + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -216,202 +216,227 @@ contract('PreSaleSTO', accounts => { LatestTime: ${latestTime()}\n ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol); }); - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + it("Should fail to launch the STO due to endTime is 0", async () => { + let bytesSTO = encodeModuleCall(STOParameters, [0]); + + await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); + }); + + it("Should successfully attach the STO factory with the security token", async () => { + endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time + let bytesSTO = encodeModuleCall(STOParameters, [endTime]); + + const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); + + assert.equal(tx.logs[2].args._type, stoKey, "PreSaleSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "PreSaleSTO", + "PreSaleSTOFactory module was not added" + ); + I_PreSaleSTO = PreSaleSTO.at(tx.logs[2].args._module); + }); }); - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it('Should fail to launch the STO due to endTime is 0', async () => { - let bytesSTO = encodeModuleCall(STOParameters, [0]); - - await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); - }); - - it('Should successfully attach the STO factory with the security token', async () => { - endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time - let bytesSTO = encodeModuleCall(STOParameters, [endTime]); + describe("verify the data of STO", async () => { - const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); + it("Should verify the configuration of the STO", async() => { + assert.equal( + (await I_PreSaleSTO.endTime.call()).toNumber(), + endTime, + "STO Configuration doesn't set as expected" + ); + }); - assert.equal(tx.logs[2].args._type, stoKey, "PreSaleSTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'PreSaleSTO', - 'PreSaleSTOFactory module was not added' - ); - I_PreSaleSTO = PreSaleSTO.at(tx.logs[2].args._module); + it("Should get the permissions", async() => { + let perm = await I_PreSaleSTO.getPermissions.call(); + assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), "PRE_SALE_ADMIN"); + }); }); - }); - describe('verify the data of STO', async () => { - it('Should verify the configuration of the STO', async () => { - assert.equal((await I_PreSaleSTO.endTime.call()).toNumber(), endTime, "STO Configuration doesn't set as expected"); - }); + describe("Buy tokens", async() => { + + it("Should allocate the tokens -- failed due to investor not on whitelist", async () => { + + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0)); + }); + + it("Should Buy the tokens", async() => { + fromTime = latestTime(); + toTime = fromTime + duration.days(100); + expiryTime = toTime + duration.days(100); + + // Add the Investor in to the whitelist + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + fromTime, + toTime, + expiryTime, + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(duration.days(1)); + await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_issuer }); + + assert.equal( + (await I_PreSaleSTO.getRaised.call(0)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1 + ); + console.log(await I_PreSaleSTO.getNumberInvestors.call()); + assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 1); + // assert.isTrue(false); + + }); + + it("Should allocate the tokens -- failed due to msg.sender is not pre sale admin", async () => { + + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver })); + }); + + it("Should allocate tokens to multiple investors", async() => { + fromTime = latestTime(); + toTime = fromTime + duration.days(100); + expiryTime = toTime + duration.days(100); + + // Add the Investor in to the whitelist + let tx1 = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx1.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); + + // Add the Investor in to the whitelist + let tx2 = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + fromTime, + toTime, + expiryTime, + true, + { + from: account_issuer, + gas: 6000000 + }); + + assert.equal(tx2.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); + + await I_PreSaleSTO.allocateTokensMulti([account_investor2, account_investor3], [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], [0,0], [web3.utils.toWei('1000', 'ether'), web3.utils.toWei('1000', 'ether')], {from: account_issuer }); + + assert.equal( + (await I_PreSaleSTO.getRaised.call(1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 2000 + ); + assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 3); + }); + + it("Should failed at the time of buying the tokens -- Because STO has started", async() => { + await increaseTime(duration.days(100)); // increased beyond the end time of the STO + + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, {from: account_issuer})); + }); - it('Should get the permissions', async () => { - let perm = await I_PreSaleSTO.getPermissions.call(); - assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), 'PRE_SALE_ADMIN'); }); - }); - describe('Buy tokens', async () => { - it('Should allocate the tokens -- failed due to investor not on whitelist', async () => { - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0)); + describe("Reclaim poly sent to STO by mistake", async() => { + + it("Should fail to reclaim POLY because token contract address is 0 address", async() => { + let value = web3.utils.toWei('100','ether'); + await I_PolyToken.getTokens(value, account_investor1); + await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); + + + await catchRevert(I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); + }); + + it("Should successfully reclaim POLY", async() => { + let value = web3.utils.toWei('100','ether'); + await I_PolyToken.getTokens(value, account_investor1); + let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); + let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); + let initContractBalance = await I_PolyToken.balanceOf(I_PreSaleSTO.address); + + await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); + await I_PreSaleSTO.reclaimERC20(I_PolyToken.address, { from: token_owner }); + assert.equal((await I_PolyToken.balanceOf(account_investor1)).toNumber(), initInvestorBalance.sub(value).toNumber(), "tokens are not transfered out from investor account"); + assert.equal((await I_PolyToken.balanceOf(token_owner)).toNumber(), initOwnerBalance.add(value).add(initContractBalance).toNumber(), "tokens are not added to the owner account"); + assert.equal((await I_PolyToken.balanceOf(I_PreSaleSTO.address)).toNumber(), 0, "tokens are not trandfered out from STO contract"); + }); }); - it('Should Buy the tokens', async () => { - fromTime = latestTime(); - toTime = fromTime + duration.days(100); - expiryTime = toTime + duration.days(100); - - // Add the Investor in to the whitelist - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(duration.days(1)); - await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, { - from: account_issuer - }); - - assert.equal((await I_PreSaleSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - console.log(await I_PreSaleSTO.getNumberInvestors.call()); - assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 1); - // assert.isTrue(false); - }); + describe("Test cases for the PresaleSTOFactory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal(await I_PreSaleSTOFactory.setupCost.call(),0); + assert.equal(await I_PreSaleSTOFactory.getType.call(),3); + assert.equal(web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()) + .replace(/\u0000/g, ''), + "PreSaleSTO", + "Wrong Module added"); + assert.equal(await I_PreSaleSTOFactory.getDescription.call(), + "Allows Issuer to configure pre-sale token allocations", + "Wrong Module added"); + assert.equal(await I_PreSaleSTOFactory.getTitle.call(), + "PreSale STO", + "Wrong Module added"); + assert.equal(await I_PreSaleSTOFactory.getInstructions.call(), + "Configure and track pre-sale token allocations", + "Wrong Module added"); + let tags = await I_PreSaleSTOFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''),"Presale"); + }); + }); - it('Should allocate the tokens -- failed due to msg.sender is not pre sale admin', async () => { - await catchRevert( - I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, { - from: account_fundsReceiver - }) - ); - }); - - it('Should allocate tokens to multiple investors', async () => { - fromTime = latestTime(); - toTime = fromTime + duration.days(100); - expiryTime = toTime + duration.days(100); - - // Add the Investor in to the whitelist - let tx1 = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx1.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); - - // Add the Investor in to the whitelist - let tx2 = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { - from: account_issuer, - gas: 6000000 - }); - - assert.equal(tx2.logs[0].args._investor, account_investor3, 'Failed in adding the investor in whitelist'); - - await I_PreSaleSTO.allocateTokensMulti( - [account_investor2, account_investor3], - [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], - [0, 0], - [web3.utils.toWei('1000', 'ether'), web3.utils.toWei('1000', 'ether')], - { from: account_issuer } - ); - - assert.equal((await I_PreSaleSTO.getRaised.call(1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2000); - assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 3); - }); - - it('Should failed at the time of buying the tokens -- Because STO has started', async () => { - await increaseTime(duration.days(100)); // increased beyond the end time of the STO - - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, { from: account_issuer })); - }); - }); - - describe('Reclaim poly sent to STO by mistake', async () => { - it('Should fail to reclaim POLY because token contract address is 0 address', async () => { - let value = web3.utils.toWei('100', 'ether'); - await I_PolyToken.getTokens(value, account_investor1); - await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); - - await catchRevert(I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); - }); - - it('Should successfully reclaim POLY', async () => { - let value = web3.utils.toWei('100', 'ether'); - await I_PolyToken.getTokens(value, account_investor1); - let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); - let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); - let initContractBalance = await I_PolyToken.balanceOf(I_PreSaleSTO.address); - - await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); - await I_PreSaleSTO.reclaimERC20(I_PolyToken.address, { from: token_owner }); - assert.equal( - (await I_PolyToken.balanceOf(account_investor1)).toNumber(), - initInvestorBalance.sub(value).toNumber(), - 'tokens are not transfered out from investor account' - ); - assert.equal( - (await I_PolyToken.balanceOf(token_owner)).toNumber(), - initOwnerBalance - .add(value) - .add(initContractBalance) - .toNumber(), - 'tokens are not added to the owner account' - ); - assert.equal((await I_PolyToken.balanceOf(I_PreSaleSTO.address)).toNumber(), 0, 'tokens are not trandfered out from STO contract'); - }); - }); - - describe('Test cases for the PresaleSTOFactory', async () => { - it('should get the exact details of the factory', async () => { - assert.equal(await I_PreSaleSTOFactory.setupCost.call(), 0); - assert.equal(await I_PreSaleSTOFactory.getType.call(), 3); - assert.equal(web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()).replace(/\u0000/g, ''), 'PreSaleSTO', 'Wrong Module added'); - assert.equal( - await I_PreSaleSTOFactory.getDescription.call(), - 'Allows Issuer to configure pre-sale token allocations', - 'Wrong Module added' - ); - assert.equal(await I_PreSaleSTOFactory.getTitle.call(), 'PreSale STO', 'Wrong Module added'); - assert.equal( - await I_PreSaleSTOFactory.getInstructions.call(), - 'Configure and track pre-sale token allocations', - 'Wrong Module added' - ); - let tags = await I_PreSaleSTOFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), 'Presale'); - }); - }); }); diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index df5a294ea..15efa13b9 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -24,199 +24,211 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port -contract('SecurityTokenRegistry', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_fundsReceiver; - let account_delegate; - let account_temp; - let dummy_token; - - let balanceOfReceiver; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(100); - - let ID_snap; - const message = 'Transaction Should Fail!!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_SecurityTokenRegistryV2; - let I_DummySTOFactory; - let I_STVersion; - let I_SecurityToken; - let I_DummySTO; - let I_PolyToken; - let I_STFactory; - let I_STFactory002; - let I_SecurityToken002; - let I_STFactory003; - let I_PolymathRegistry; - let I_SecurityTokenRegistryProxy; - let I_STRProxied; - let I_MRProxied; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = 'Demo Token'; - const symbol = 'DET'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - //Security Token Detials (Version 2) - const name2 = 'Demo2 Token'; - const symbol2 = 'DET2'; - const tokenDetails2 = 'This is equity type of issuance'; - - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - const newRegFee = web3.utils.toWei('300'); - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - - // Capped STO details - const cap = web3.utils.toWei('10000'); - const someString = 'Hello string'; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_investor1 = accounts[9]; - account_investor2 = accounts[6]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - account_temp = accounts[8]; - token_owner = account_issuer; - dummy_token = accounts[3]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // Step 6: Deploy the STversionProxy contract +contract('SecurityTokenRegistry', accounts => { - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_fundsReceiver; + let account_delegate; + let account_temp; + let dummy_token; + + let balanceOfReceiver; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(100); + + let ID_snap; + const message = "Transaction Should Fail!!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_SecurityTokenRegistryV2; + let I_DummySTOFactory; + let I_STVersion; + let I_SecurityToken; + let I_DummySTO; + let I_PolyToken; + let I_STFactory; + let I_STFactory002; + let I_SecurityToken002; + let I_STFactory003; + let I_PolymathRegistry; + let I_SecurityTokenRegistryProxy; + let I_STRProxied; + let I_MRProxied; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = "Demo Token"; + const symbol = "DET"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + + //Security Token Detials (Version 2) + const name2 = "Demo2 Token"; + const symbol2 = "DET2"; + const tokenDetails2 = "This is equity type of issuance"; + + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + const newRegFee = web3.utils.toWei("300"); + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + + // Capped STO details + const cap = web3.utils.toWei("10000"); + const someString = "Hello string"; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_investor1 = accounts[9]; + account_investor2 = accounts[6]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + account_temp = accounts[8]; + token_owner = account_issuer; + dummy_token = accounts[3]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 3: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + + // Step 6: Deploy the STversionProxy contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - // STEP 8: Deploy the CappedSTOFactory + // STEP 8: Deploy the CappedSTOFactory - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 1000 * Math.pow(10, 18), 0, 0, { from: token_owner }); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 1000 * Math.pow(10, 18), 0, 0,{ from: token_owner }); - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'TestSTOFactory contract was not deployed' - ); + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "TestSTOFactory contract was not deployed" + ); - // Step 9: Deploy the SecurityTokenRegistry + // Step 9: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - // Step 9 (a): Deploy the proxy - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + // Step 9 (a): Deploy the proxy + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - // Step 10: Deploy the FeatureRegistry + // Step 10: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); - assert.notEqual( - I_FeatureRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'FeatureRegistry contract was not deployed' - ); + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); - //Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); + //Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - // STEP 4: Register the Modules with the ModuleRegistry contract + // STEP 4: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - console.log(` + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -232,856 +244,832 @@ contract('SecurityTokenRegistry', accounts => { DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Test the initialize the function', async () => { - it('Should successfully update the implementation address -- fail because polymathRegistry address is 0x', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - '0x0000000000000000000000000000000000000000', - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), - 'tx-> revert because polymathRegistry address is 0x' - ); - }); - - it('Should successfully update the implementation address -- fail because STFactory address is 0x', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - '0x0000000000000000000000000000000000000000', - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), - 'tx-> revert because STFactory address is 0x' - ); - }); - - it('Should successfully update the implementation address -- fail because STLaunch fee is 0', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - 0, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), - 'tx-> revert because STLaunch fee is 0' - ); - }); - - it('Should successfully update the implementation address -- fail because tickerRegFee fee is 0', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - 0, - I_PolyToken.address, - account_polymath - ]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), - 'tx-> revert because tickerRegFee is 0' - ); - }); - - it('Should successfully update the implementation address -- fail because PolyToken address is 0x', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - '0x0000000000000000000000000000000000000000', - account_polymath - ]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), - 'tx-> revert because PolyToken address is 0x' - ); - }); - - it('Should successfully update the implementation address -- fail because owner address is 0x', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - '0x0000000000000000000000000000000000000000' - ]); - catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }), - 'tx-> revert because owner address is 0x' - ); - }); - - it('Should successfully update the implementation address', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - }); - }); - - describe(' Test cases of the registerTicker', async () => { - it('verify the intial parameters', async () => { - let intialised = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('initialised')); - assert.isTrue(intialised, 'Should be true'); - - let expiry = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('expiryLimit')); - assert.equal(expiry.toNumber(), 5184000, 'Expiry limit should be equal to 60 days'); - - let polytoken = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('polyToken')); - assert.equal(polytoken, I_PolyToken.address, 'Should be the polytoken address'); - - let stlaunchFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('stLaunchFee')); - assert.equal(stlaunchFee.toNumber(), initRegFee, 'Should be provided reg fee'); - - let tickerRegFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('tickerRegFee')); - assert.equal(tickerRegFee.toNumber(), tickerRegFee, 'Should be provided reg fee'); - - let polymathRegistry = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('polymathRegistry')); - assert.equal(polymathRegistry, I_PolymathRegistry.address, 'Should be the address of the polymath registry'); - - let owner = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')); - assert.equal(owner, account_polymath, 'Should be the address of the registry owner'); - }); - - it("Can't call the intialize function again", async () => { - catchRevert( - I_STRProxied.initialize( - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ), - "tx revert -> Can't call the intialize function again" - ); - }); - - it('Should fail to register ticker if tickerRegFee not approved', async () => { - catchRevert( - I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }), - 'tx revert -> POLY allowance not provided for registration fee' - ); - }); - - it('Should fail to register ticker if owner is 0x', async () => { - await I_PolyToken.getTokens(initRegFee, account_temp); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp }); - - catchRevert( - I_STRProxied.registerTicker('0x0000000000000000000000000000000000000000', symbol, name, { from: account_temp }), - 'tx revert -> owner should not be 0x' - ); - }); - - it('Should fail to register ticker due to the symbol length is 0', async () => { - catchRevert(I_STRProxied.registerTicker(account_temp, '', name, { from: account_temp }), 'tx revert -> Symbol Length is 0'); - }); - - it('Should fail to register ticker due to the symbol length is greater than 10', async () => { - catchRevert( - I_STRProxied.registerTicker(account_temp, 'POLYMATHNET', name, { from: account_temp }), - 'tx revert -> Symbol Length is greater than 10' - ); - }); - - it('Should register the ticker before the generation of the security token', async () => { - let tx = await I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); - }); - - it('Should fail to register same symbol again', async () => { - // Give POLY to token issuer - await I_PolyToken.getTokens(initRegFee, token_owner); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - // Call registration function - catchRevert( - I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }), - 'tx revert -> Symbol is already alloted to someone else' - ); - }); - - it('Should successfully register pre registerd ticker if expiry is reached', async () => { - await increaseTime(5184000 + 100); // 60(5184000) days of expiry + 100 sec for buffer - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); - }); - - it('Should fail to register ticker if registration is paused', async () => { - await I_STRProxied.pause({ from: account_polymath }); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - - catchRevert(I_STRProxied.registerTicker(token_owner, 'AAA', name, { from: token_owner }), 'tx revert -> Registration is paused'); - }); - - it('Should fail to pause if already paused', async () => { - catchRevert(I_STRProxied.pause({ from: account_polymath }), 'tx revert -> Registration is already paused'); - }); - - it('Should successfully register ticker if registration is unpaused', async () => { - await I_STRProxied.unpause({ from: account_polymath }); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, 'AAA', name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, 'AAA', `Symbol should be AAA`); - }); - - it('Should fail to unpause if already unpaused', async () => { - catchRevert(I_STRProxied.unpause({ from: account_polymath }), 'tx revert -> Registration is already unpaused'); - }); - }); - - describe('Test cases for the expiry limit', async () => { - it('Should fail to set the expiry limit because msg.sender is not owner', async () => { - catchRevert(I_STRProxied.changeExpiryLimit(duration.days(10), { from: account_temp }), 'tx revert -> msg.sender is not owner'); - }); - - it('Should successfully set the expiry limit', async () => { - await I_STRProxied.changeExpiryLimit(duration.days(10), { from: account_polymath }); - assert.equal( - (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('expiryLimit'))).toNumber(), - duration.days(10), - 'Failed to change the expiry limit' - ); - }); - - it('Should fail to set the expiry limit because new expiry limit is lesser than one day', async () => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.seconds(5000), { from: account_polymath }), - 'tx revert -> New expiry limit is lesser than one day' - ); - }); - }); - - describe('Test cases for the getTickerDetails', async () => { - it('Should get the details of the symbol', async () => { - let tx = await I_STRProxied.getTickerDetails.call(symbol); - assert.equal(tx[0], token_owner, 'Should equal to the rightful owner of the ticker'); - assert.equal(tx[3], name, `Name of the token should equal to ${name}`); - assert.equal(tx[4], false, 'Status if the symbol should be undeployed -- false'); - }); - - it('Should get the details of unregistered token', async () => { - let tx = await I_STRProxied.getTickerDetails.call('TORO'); - assert.equal(tx[0], '0x0000000000000000000000000000000000000000', 'Should be 0x as ticker is not exists in the registry'); - assert.equal(tx[3], '', 'Should be an empty string'); - assert.equal(tx[4], false, 'Status if the symbol should be undeployed -- false'); - }); - }); - - describe('Generate SecurityToken', async () => { - it('Should get the ticker details successfully and prove the data is not storing in to the logic contract', async () => { - let data = await I_STRProxied.getTickerDetails(symbol, { from: token_owner }); - assert.equal(data[0], token_owner, 'Token owner should be equal'); - assert.equal(data[3], name, 'Name of the token should match with the registered symbol infor'); - assert.equal(data[4], false, 'Token is not launched yet so it should return False'); - data = await I_SecurityTokenRegistry.getTickerDetails(symbol, { from: token_owner }); - console.log('This is the data from the original securityTokenRegistry contract'); - assert.equal(data[0], '0x0000000000000000000000000000000000000000', 'Token owner should be 0x'); - }); - - it('Should fail to generate new security token if fee not provided', async () => { - await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner }); - - catchRevert( - I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), - 'tx revert -> POLY allowance not provided for registration fee' - ); - }); - - it('Should fail to generate token if registration is paused', async () => { - await I_STRProxied.pause({ from: account_polymath }); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - - catchRevert( - I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), - 'tx revert -> Registration is paused' - ); - }); - - it('Should fail to generate the securityToken -- Because ticker length is 0', async () => { - await I_STRProxied.unpause({ from: account_polymath }); - - catchRevert( - I_STRProxied.generateSecurityToken(name, '', tokenDetails, false, { from: token_owner }), - 'tx revert -> Zero ticker length is not allowed' - ); - }); - - it('Should fail to generate the securityToken -- Because name length is 0', async () => { - catchRevert( - I_STRProxied.generateSecurityToken('', symbol, tokenDetails, false, { from: token_owner }), - 'tx revert -> 0 name length is not allowed' - ); - }); - - it('Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker', async () => { - catchRevert( - I_STRProxied.generateSecurityToken('', symbol, tokenDetails, false, { from: account_temp }), - 'tx revert -> Because msg.sender is not the rightful owner of the ticker' - ); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTrasnferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey, `Should be equal to the ${transferManagerKey}`); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); - - it('Should fail to generate the SecurityToken when token is already deployed with the same symbol', async () => { - catchRevert( - I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), - 'tx revert -> Because ticker is already in use' - ); - }); - }); - - describe('Generate SecurityToken v2', async () => { - it('Should deploy the st version 2', async () => { - // Step 7: Deploy the STFactory contract - - I_STFactory002 = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual( - I_STFactory002.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'STFactory002 contract was not deployed' - ); - await I_STRProxied.setProtocolVersion(I_STFactory002.address, 0, 2, 0, { from: account_polymath }); - let _protocol = await I_STRProxied.getProtocolVersion.call(); - assert.equal(_protocol[0], 0); - assert.equal(_protocol[1], 2); - assert.equal(_protocol[2], 0); - }); - - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol2, name2, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, symbol2, `Symbol should be ${symbol2}`); - }); - - it('Should generate the new security token with version 2', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); - - I_SecurityToken002 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - let tokens = await I_STRProxied.getTokensByOwner.call(token_owner); - assert.equal(tokens[0], I_SecurityToken.address); - assert.equal(tokens[1], I_SecurityToken002.address); - - const log = await promisifyLogWatch(I_SecurityToken002.ModuleAdded({ from: _blockNo }), 1); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); - }); - - describe('Deploy the new SecurityTokenRegistry', async () => { - it('Should deploy the new SecurityTokenRegistry contract logic', async () => { - I_SecurityTokenRegistryV2 = await SecurityTokenRegistryMock.new({ from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistryV2.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - }); - - it('Should fail to upgrade the logic contract of the STRProxy -- bad owner', async () => { - await I_STRProxied.pause({ from: account_polymath }); - - catchRevert( - I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryV2.address, { from: account_temp }), - 'tx revert -> bad owner' - ); - }); - - it('Should upgrade the logic contract into the STRProxy', async () => { - await I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryV2.address, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - assert.isTrue(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')), 'Paused value should be false'); - }); - - it('Should check the old data persist or not', async () => { - let data = await I_STRProxied.getTickerDetails.call(symbol); - assert.equal(data[0], token_owner, 'Should be equal to the token owner address'); - assert.equal(data[3], name, 'Should be equal to the name of the token that is provided earlier'); - assert.isTrue(data[4], 'Token status should be deployed == true'); - }); - - it('Should unpause the logic contract', async () => { - await I_STRProxied.unpause({ from: account_polymath }); - assert.isFalse(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')), 'Paused value should be false'); - }); - }); - - describe('Generate custom tokens', async () => { - it('Should fail if msg.sender is not polymath', async () => { - catchRevert( - I_STRProxied.modifySecurityToken('LOGAN', 'LOG', account_temp, dummy_token, 'I am custom ST', latestTime(), { - from: account_delegate - }), - 'tx revert -> msg.sender is not polymath account' - ); - }); - - it('Should fail to generate the custom security token -- name should not be 0 length ', async () => { - catchRevert( - I_STRProxied.modifySecurityToken('', 'LOG', account_temp, dummy_token, 'I am custom ST', latestTime(), { from: account_polymath }), - 'tx revert -> name should not be 0 length' - ); - }); - - it('Should fail if ST address is 0 address', async () => { - catchRevert( - I_STRProxied.modifySecurityToken('LOGAN', 'LOG', account_temp, 0, 'I am custom ST', latestTime(), { from: account_polymath }), - 'tx revert -> Security token address is 0' - ); - }); - - it('Should fail if symbol length is 0', async () => { - catchRevert( - I_STRProxied.modifySecurityToken('', '', account_temp, dummy_token, 'I am custom ST', latestTime(), { from: account_polymath }), - 'tx revert -> zero length of the symbol is not allowed' - ); - }); - - it('Should fail to generate the custom ST -- deployedAt param is 0', async () => { - catchRevert( - I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, 'I am custom ST', 0, { from: account_polymath }), - 'tx revert -> because deployedAt param is 0' - ); - }); - - it('Should successfully generate custom token', async () => { - // Register the new ticker -- Fulfiling the TickerStatus.ON condition - await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp }); - let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - await I_STRProxied.registerTicker(account_temp, 'LOG', 'LOGAN', { from: account_temp }); - tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - // Generating the ST - let tx = await I_STRProxied.modifySecurityToken('LOGAN', 'LOG', account_temp, dummy_token, 'I am custom ST', latestTime(), { - from: account_polymath - }); - tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - assert.equal(tx.logs[1].args._ticker, 'LOG', 'Symbol should match with the registered symbol'); - assert.equal( - tx.logs[1].args._securityTokenAddress, - dummy_token, - `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken` - ); - let symbolDetails = await I_STRProxied.getTickerDetails('LOG'); - assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); - assert.equal(symbolDetails[3], 'LOGAN', `Name of the symbol should be LOGAN`); - }); - - it('Should successfully generate the custom token', async () => { - // Fulfilling the TickerStatus.NN condition - // - // await catchRevert(I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath})); - // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); - // await increaseTime(duration.days(1)); - let tx = await I_STRProxied.modifySecurityToken('LOGAN2', 'LOG2', account_temp, dummy_token, 'I am custom ST', latestTime(), { - from: account_polymath - }); - assert.equal(tx.logs[1].args._ticker, 'LOG2', 'Symbol should match with the registered symbol'); - assert.equal( - tx.logs[1].args._securityTokenAddress, - dummy_token, - `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken` - ); - assert.equal(tx.logs[0].args._owner, account_temp, `Token owner should be ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, 'LOG2', `Symbol should be LOG2`); - let symbolDetails = await I_STRProxied.getTickerDetails('LOG2'); - assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); - assert.equal(symbolDetails[3], 'LOGAN2', `Name of the symbol should be LOGAN`); - }); - }); - - describe('Test case for modifyTicker', async () => { - it('Should add the custom ticker --failed because of bad owner', async () => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', latestTime(), latestTime() + duration.days(10), false, { - from: account_temp - }), - 'tx revert -> failed beacause of bad owner0' - ); - }); - - it('Should add the custom ticker --fail ticker length should not be 0', async () => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, '', 'Ether', latestTime(), latestTime() + duration.days(10), false, { - from: account_polymath - }), - 'tx revert -> failed beacause ticker length should not be 0' - ); - }); - - it('Should add the custom ticker --failed because time should not be 0', async () => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', 0, latestTime() + duration.days(10), false, { from: account_polymath }), - 'tx revert -> failed because time should not be 0' - ); - }); - - it('Should add the custom ticker --failed because registeration date is greater than the expiryDate', async () => { - catchRevert( - I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', latestTime(), latestTime() - duration.minutes(10), false, { - from: account_polymath - }), - 'tx revert -> failed because registeration date is greater than the expiryDate' - ); - }); - - it('Should add the custom ticker --failed because owner should not be 0x', async () => { - catchRevert( - I_STRProxied.modifyTicker( - '0x000000000000000000000000000000000000000000', - 'ETH', - 'Ether', - latestTime(), - latestTime() + duration.minutes(10), - false, - { from: account_polymath } - ), - 'tx revert -> failed because owner should not be 0x' - ); - }); - - it('Should add the new custom ticker', async () => { - let tx = await I_STRProxied.modifyTicker(account_temp, 'ETH', 'Ether', latestTime(), latestTime() + duration.minutes(10), false, { - from: account_polymath - }); - assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, 'ETH', 'Should be equal to ETH'); - }); - - it('Should change the details of the existing ticker', async () => { - let tx = await I_STRProxied.modifyTicker(token_owner, 'ETH', 'Ether', latestTime(), latestTime() + duration.minutes(10), false, { - from: account_polymath - }); - assert.equal(tx.logs[0].args._owner, token_owner); - }); - }); - - describe('Test cases for the transferTickerOwnership()', async () => { - it('Should able to transfer the ticker ownership -- failed because token is not deployed having the same ticker', async () => { - catchRevert( - I_STRProxied.transferTickerOwnership(account_issuer, 'ETH', { from: account_temp }), - 'tx revert -> failed because token is not deployed having the same ticker' - ); - }); - - it('Should able to transfer the ticker ownership -- failed because new owner is 0x', async () => { - await I_SecurityToken002.transferOwnership(account_temp, { from: token_owner }); - catchRevert( - I_STRProxied.transferTickerOwnership('0x00000000000000000000000000000000000000000', symbol2, { from: token_owner }), - 'tx revert -> failed because new owner is 0x' - ); - }); - - it('Should able to transfer the ticker ownership -- failed because ticker is of zero length', async () => { - catchRevert( - I_STRProxied.transferTickerOwnership(account_temp, '', { from: token_owner }), - 'tx revert -> failed because ticker is of zero length' - ); - }); - - it('Should able to transfer the ticker ownership', async () => { - let tx = await I_STRProxied.transferTickerOwnership(account_temp, symbol2, { from: token_owner, gas: 5000000 }); - assert.equal(tx.logs[0].args._newOwner, account_temp); - let symbolDetails = await I_STRProxied.getTickerDetails.call(symbol2); - assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); - assert.equal(symbolDetails[3], name2, `Name of the symbol should be ${name2}`); - }); - }); - - describe('Test case for the changeSecurityLaunchFee()', async () => { - it('Should able to change the STLaunchFee-- failed because of bad owner', async () => { - catchRevert( - I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei('500'), { from: account_temp }), - 'tx revert -> failed because of bad owner' - ); - }); - - it('Should able to change the STLaunchFee-- failed because of putting the same fee', async () => { - catchRevert( - I_STRProxied.changeSecurityLaunchFee(initRegFee, { from: account_polymath }), - 'tx revert -> failed because of putting the same fee' - ); - }); - - it('Should able to change the STLaunchFee', async () => { - let tx = await I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei('500'), { from: account_polymath }); - assert.equal(tx.logs[0].args._newFee, web3.utils.toWei('500')); - let stLaunchFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3('stLaunchFee')); - assert.equal(stLaunchFee, web3.utils.toWei('500')); - }); - }); - - describe('Test cases for the changeExpiryLimit()', async () => { - it('Should able to change the ExpiryLimit-- failed because of bad owner', async () => { - catchRevert(I_STRProxied.changeExpiryLimit(duration.days(15), { from: account_temp }), 'tx revert -> failed because of bad owner'); - }); - - it('Should able to change the ExpiryLimit-- failed because expirylimit is less than 1 day', async () => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.minutes(50), { from: account_polymath }), - 'tx revert -> failed because expirylimit is less than 1 day' - ); - }); - - it('Should able to change the ExpiryLimit', async () => { - let tx = await I_STRProxied.changeExpiryLimit(duration.days(20), { from: account_polymath }); - assert.equal(tx.logs[0].args._newExpiry, duration.days(20)); - let expiry = await I_STRProxied.getUintValues(web3.utils.soliditySha3('expiryLimit')); - assert.equal(expiry, duration.days(20)); - }); - }); - - describe('Test cases for the changeTickerRegistrationFee()', async () => { - it('Should able to change the TickerRegFee-- failed because of bad owner', async () => { - catchRevert( - I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei('500'), { from: account_temp }), - 'tx revert -> failed because of bad owner' - ); - }); - - it('Should able to change the TickerRegFee-- failed because of putting the same fee', async () => { - catchRevert( - I_STRProxied.changeTickerRegistrationFee(initRegFee, { from: account_polymath }), - 'tx revert -> failed because of putting the same fee' - ); - }); - - it('Should able to change the TickerRegFee', async () => { - let tx = await I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei('400'), { from: account_polymath }); - assert.equal(tx.logs[0].args._newFee, web3.utils.toWei('400')); - let tickerRegFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3('tickerRegFee')); - assert.equal(tickerRegFee, web3.utils.toWei('400')); - }); - - it('Should fail to register the ticker with the old fee', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - catchRevert( - I_STRProxied.registerTicker(token_owner, 'POLY', 'Polymath', { from: token_owner }), - 'tx revert -> failed because of ticker registeration fee gets change' - ); - }); - - it('Should register the ticker with the new fee', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('1000'), token_owner); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, 'POLY', 'Polymath', { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); - assert.equal(tx.logs[0].args._ticker, 'POLY', `Symbol should be POLY`); - }); - - it('Should fail to launch the securityToken with the old launch fee', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - catchRevert( - I_STRProxied.generateSecurityToken('Polymath', 'POLY', tokenDetails, false, { from: token_owner }), - 'tx revert -> failed because of old launch fee' - ); - }); - - it('Should launch the the securityToken', async () => { - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('500'), { from: token_owner }); - let tx = await I_STRProxied.generateSecurityToken('Polymath', 'POLY', tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, 'POLY', "SecurityToken doesn't get deployed"); - }); - }); - - describe('Test case for the update poly token', async () => { - it('Should change the polytoken address -- failed because of bad owner', async () => { - catchRevert(I_STRProxied.updatePolyTokenAddress(dummy_token, { from: account_temp }), 'tx revert -> failed because of bad owner'); - }); - - it('Should change the polytoken address -- failed because of 0x address', async () => { - catchRevert( - I_STRProxied.updatePolyTokenAddress('0x0000000000000000000000000000000000000000000', { from: account_polymath }), - 'tx revert -> failed because 0x address' - ); - }); - - it('Should successfully change the polytoken address', async () => { - let _id = await takeSnapshot(); - await I_STRProxied.updatePolyTokenAddress(dummy_token, { from: account_polymath }); - assert.equal(await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3('polyToken')), dummy_token); - await revertToSnapshot(_id); - }); - }); - - describe('Test cases for getters', async () => { - it('Should get the security token address', async () => { - let address = await I_STRProxied.getSecurityTokenAddress.call(symbol); - assert.equal(address, I_SecurityToken.address); - }); - - it('Should get the security token data', async () => { - let data = await I_STRProxied.getSecurityTokenData.call(I_SecurityToken.address); - assert.equal(data[0], symbol); - assert.equal(data[1], token_owner); - }); - - it('Should get the tickers by owner', async () => { - let tickersList = await I_STRProxied.getTickersByOwner.call(token_owner); - assert.equal(tickersList.length, 4); - let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); - console.log(tickersListArray); - assert.equal(tickersListArray.length, 3); - }); - }); - - describe('Test case for the Removing the ticker', async () => { - it('Should remove the ticker from the polymath ecosystem -- bad owner', async () => { - catchRevert( - I_STRProxied.removeTicker(symbol2, { from: account_investor1 }), - 'tx revert -> failed because msg.sender should be account_polymath' - ); - }); - - it("Should remove the ticker from the polymath ecosystem -- fail because ticker doesn't exist in the ecosystem", async () => { - catchRevert( - I_STRProxied.removeTicker('HOLA', { from: account_polymath }), - "tx revert -> failed because ticker doesn't exist in the polymath ecosystem" - ); }); - it('Should successfully remove the ticker from the polymath ecosystem', async () => { - let tx = await I_STRProxied.removeTicker(symbol2, { from: account_polymath }); - assert.equal(tx.logs[0].args._ticker, symbol2, "Ticker doesn't get deleted successfully"); - }); - }); - - describe(' Test cases of the registerTicker', async () => { - it('Should register the ticker 1', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('1000'), { from: account_temp }); - let tx = await I_STRProxied.registerTicker(account_temp, 'TOK1', '', { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, 'TOK1', `Symbol should be TOK1`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - - it('Should register the ticker 2', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('1000'), { from: account_temp }); - let tx = await I_STRProxied.registerTicker(account_temp, 'TOK2', '', { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, 'TOK2', `Symbol should be TOK2`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - - it('Should register the ticker 3', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('1000'), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei('1000'), { from: account_temp }); - let tx = await I_STRProxied.registerTicker(account_temp, 'TOK3', '', { from: account_temp }); - assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, 'TOK3', `Symbol should be TOK3`); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); + describe("Test the initialize the function", async() => { + + it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, ["0x0000000000000000000000000000000000000000", I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because polymathRegistry address is 0x" + ); + }) + + it("Should successfully update the implementation address -- fail because STFactory address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, "0x0000000000000000000000000000000000000000", initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because STFactory address is 0x" + ); + }); + + it("Should successfully update the implementation address -- fail because STLaunch fee is 0", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, 0, initRegFee, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because STLaunch fee is 0" + ); + }); + + it("Should successfully update the implementation address -- fail because tickerRegFee fee is 0", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, 0, I_PolyToken.address, account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because tickerRegFee is 0" + ); + }); + + it("Should successfully update the implementation address -- fail because PolyToken address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, "0x0000000000000000000000000000000000000000", account_polymath]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because PolyToken address is 0x" + ); + }); + + it("Should successfully update the implementation address -- fail because owner address is 0x", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, "0x0000000000000000000000000000000000000000"]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + "tx-> revert because owner address is 0x" + ); + }); + + it("Should successfully update the implementation address", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + }); + }) + + + describe(" Test cases of the registerTicker", async() => { + + it("verify the intial parameters", async() => { + let intialised = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("initialised")); + assert.isTrue(intialised, "Should be true"); + + let expiry = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit")); + assert.equal(expiry.toNumber(), 5184000, "Expiry limit should be equal to 60 days"); + + let polytoken = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")); + assert.equal(polytoken, I_PolyToken.address, "Should be the polytoken address"); + + let stlaunchFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("stLaunchFee")); + assert.equal(stlaunchFee.toNumber(), initRegFee, "Should be provided reg fee"); + + let tickerRegFee = await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("tickerRegFee")); + assert.equal(tickerRegFee.toNumber(), tickerRegFee, "Should be provided reg fee"); + + let polymathRegistry = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry")); + assert.equal(polymathRegistry, I_PolymathRegistry.address, "Should be the address of the polymath registry"); + + let owner = await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("owner")); + assert.equal(owner, account_polymath, "Should be the address of the registry owner"); + }); + + it("Can't call the intialize function again", async() => { + catchRevert( + I_STRProxied.initialize(I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath), + "tx revert -> Can't call the intialize function again" + ); + }) + + it("Should fail to register ticker if tickerRegFee not approved", async() => { + catchRevert( + I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }), + "tx revert -> POLY allowance not provided for registration fee" + ); + }); + + it("Should fail to register ticker if owner is 0x", async() => { + await I_PolyToken.getTokens(initRegFee, account_temp); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); + + catchRevert( + I_STRProxied.registerTicker("0x0000000000000000000000000000000000000000", symbol, name, { from: account_temp }), + "tx revert -> owner should not be 0x" + ); + }); + + it("Should fail to register ticker due to the symbol length is 0", async() => { + catchRevert( + I_STRProxied.registerTicker(account_temp, "", name, { from: account_temp }), + "tx revert -> Symbol Length is 0" + ); + }); + + it("Should fail to register ticker due to the symbol length is greater than 10", async() => { + catchRevert( + I_STRProxied.registerTicker(account_temp, "POLYMATHNET", name, { from: account_temp }), + "tx revert -> Symbol Length is greater than 10" + ); + }); + + it("Should register the ticker before the generation of the security token", async () => { + let tx = await I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); + }); + + it("Should fail to register same symbol again", async() => { + // Give POLY to token issuer + await I_PolyToken.getTokens(initRegFee, token_owner); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + // Call registration function + catchRevert( + I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }), + "tx revert -> Symbol is already alloted to someone else" + ); + }); + + it("Should successfully register pre registerd ticker if expiry is reached", async() => { + await increaseTime(5184000 + 100); // 60(5184000) days of expiry + 100 sec for buffer + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); + }); + + it("Should fail to register ticker if registration is paused", async() => { + await I_STRProxied.pause({ from: account_polymath}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + + catchRevert( + I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }), + "tx revert -> Registration is paused" + ); + }); + + it("Should fail to pause if already paused", async() => { + catchRevert( + I_STRProxied.pause({ from: account_polymath}), + "tx revert -> Registration is already paused" + ); + }); + + it("Should successfully register ticker if registration is unpaused", async() => { + await I_STRProxied.unpause({ from: account_polymath}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, "AAA", `Symbol should be AAA`); + }); + + it("Should fail to unpause if already unpaused", async() => { + catchRevert( + I_STRProxied.unpause({ from: account_polymath}), + "tx revert -> Registration is already unpaused" + ); + }); + }); + + describe("Test cases for the expiry limit", async() => { + + it("Should fail to set the expiry limit because msg.sender is not owner", async() => { + catchRevert( + I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_temp}), + "tx revert -> msg.sender is not owner" + ); + }); + + it("Should successfully set the expiry limit", async() => { + await I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_polymath}); + assert.equal( + (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))) + .toNumber(), + duration.days(10), + "Failed to change the expiry limit"); + }); + + it("Should fail to set the expiry limit because new expiry limit is lesser than one day", async() => { + catchRevert( + I_STRProxied.changeExpiryLimit(duration.seconds(5000), {from: account_polymath}), + "tx revert -> New expiry limit is lesser than one day" + ) + }); + }); + + describe("Test cases for the getTickerDetails", async() => { + + it("Should get the details of the symbol", async() => { + let tx = await I_STRProxied.getTickerDetails.call(symbol); + assert.equal(tx[0], token_owner, "Should equal to the rightful owner of the ticker"); + assert.equal(tx[3], name, `Name of the token should equal to ${name}`); + assert.equal(tx[4], false, "Status if the symbol should be undeployed -- false"); + }); + + it("Should get the details of unregistered token", async() => { + let tx = await I_STRProxied.getTickerDetails.call("TORO"); + assert.equal(tx[0], "0x0000000000000000000000000000000000000000", "Should be 0x as ticker is not exists in the registry"); + assert.equal(tx[3], "", "Should be an empty string"); + assert.equal(tx[4], false, "Status if the symbol should be undeployed -- false"); + }); + }); + + describe("Generate SecurityToken", async() => { + + it("Should get the ticker details successfully and prove the data is not storing in to the logic contract", async() => { + let data = await I_STRProxied.getTickerDetails(symbol, {from: token_owner}); + assert.equal(data[0], token_owner, "Token owner should be equal"); + assert.equal(data[3], name, "Name of the token should match with the registered symbol infor"); + assert.equal(data[4], false, "Token is not launched yet so it should return False"); + data = await I_SecurityTokenRegistry.getTickerDetails(symbol, {from:token_owner}); + console.log("This is the data from the original securityTokenRegistry contract"); + assert.equal(data[0], '0x0000000000000000000000000000000000000000', "Token owner should be 0x"); + }) + + it("Should fail to generate new security token if fee not provided", async() => { + await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner}); + + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> POLY allowance not provided for registration fee" + ); + }); + + it("Should fail to generate token if registration is paused", async() => { + await I_STRProxied.pause({ from: account_polymath}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> Registration is paused" + ); + }); + + it("Should fail to generate the securityToken -- Because ticker length is 0", async() => { + await I_STRProxied.unpause({ from: account_polymath}); + + catchRevert( + I_STRProxied.generateSecurityToken(name, "", tokenDetails, false, { from: token_owner }), + "tx revert -> Zero ticker length is not allowed" + ) + }) + + it("Should fail to generate the securityToken -- Because name length is 0", async() => { + catchRevert( + I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> 0 name length is not allowed" + ); + }) + + it("Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker", async() => { + catchRevert( + I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp }), + "tx revert -> Because msg.sender is not the rightful owner of the ticker" + ) + }) + + it("Should generate the new security token with the same symbol as registered above", async () => { + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTrasnferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey, `Should be equal to the ${transferManagerKey}`); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should fail to generate the SecurityToken when token is already deployed with the same symbol", async() => { + catchRevert( + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), + "tx revert -> Because ticker is already in use" + ); + }) + + }); + + describe("Generate SecurityToken v2", async() => { + + it("Should deploy the st version 2", async() => { + // Step 7: Deploy the STFactory contract + + I_STFactory002 = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory002.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory002 contract was not deployed", + ); + await I_STRProxied.setProtocolVersion(I_STFactory002.address, 0, 2, 0, { from: account_polymath }); + let _protocol = await I_STRProxied.getProtocolVersion.call(); + assert.equal(_protocol[0], 0); + assert.equal(_protocol[1], 2); + assert.equal(_protocol[2], 0); + }); + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, symbol2, name2, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, symbol2, `Symbol should be ${symbol2}`); + }); + + it("Should generate the new security token with version 2", async() => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); + + I_SecurityToken002 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + let tokens = await I_STRProxied.getTokensByOwner.call(token_owner); + assert.equal(tokens[0], I_SecurityToken.address); + assert.equal(tokens[1], I_SecurityToken002.address); + + const log = await promisifyLogWatch(I_SecurityToken002.ModuleAdded({from: _blockNo}), 1); + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + }); + + describe("Deploy the new SecurityTokenRegistry", async() => { + + it("Should deploy the new SecurityTokenRegistry contract logic", async() => { + I_SecurityTokenRegistryV2 = await SecurityTokenRegistryMock.new({ from: account_polymath }); + assert.notEqual( + I_SecurityTokenRegistryV2.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + }); + + it("Should fail to upgrade the logic contract of the STRProxy -- bad owner", async() => { + await I_STRProxied.pause({from: account_polymath}); + + catchRevert( + I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_temp}), + "tx revert -> bad owner" + ) + }) + + it("Should upgrade the logic contract into the STRProxy", async() =>{ + await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + assert.isTrue(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")), "Paused value should be false"); + }); + + it("Should check the old data persist or not", async() => { + let data = await I_STRProxied.getTickerDetails.call(symbol); + assert.equal(data[0], token_owner, "Should be equal to the token owner address"); + assert.equal(data[3], name, "Should be equal to the name of the token that is provided earlier"); + assert.isTrue(data[4], "Token status should be deployed == true"); + }); + + it("Should unpause the logic contract", async() => { + await I_STRProxied.unpause({from: account_polymath}); + assert.isFalse(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")), "Paused value should be false"); + }); + }) + + describe("Generate custom tokens", async() => { + + it("Should fail if msg.sender is not polymath", async() => { + catchRevert( + I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_delegate}), + "tx revert -> msg.sender is not polymath account" + ); + }); + + it("Should fail to generate the custom security token -- name should not be 0 length ", async() => { + catchRevert( + I_STRProxied.modifySecurityToken("", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}), + "tx revert -> name should not be 0 length" + ); + }); + + it("Should fail if ST address is 0 address", async() => { + catchRevert( + I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", latestTime(), {from: account_polymath}), + "tx revert -> Security token address is 0" + ); + }); + + it("Should fail if symbol length is 0", async() => { + catchRevert( + I_STRProxied.modifySecurityToken("", "", account_temp, dummy_token, "I am custom ST",latestTime(), {from: account_polymath}), + "tx revert -> zero length of the symbol is not allowed" + ); + }); + + it("Should fail to generate the custom ST -- deployedAt param is 0", async() => { + catchRevert( + I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, "I am custom ST", 0, {from: account_polymath}), + "tx revert -> because deployedAt param is 0" + ); + }); + + it("Should successfully generate custom token", async() => { + // Register the new ticker -- Fulfiling the TickerStatus.ON condition + await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); + let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + await I_STRProxied.registerTicker(account_temp, "LOG", "LOGAN", { from : account_temp }); + tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + // Generating the ST + let tx = await I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); + tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + assert.equal(tx.logs[1].args._ticker, "LOG", "Symbol should match with the registered symbol"); + assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token,`Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); + let symbolDetails = await I_STRProxied.getTickerDetails("LOG"); + assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); + assert.equal(symbolDetails[3], "LOGAN", `Name of the symbol should be LOGAN`); + }); + + it("Should successfully generate the custom token", async() => { + // Fulfilling the TickerStatus.NN condition + // + // await catchRevert(I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath})); + // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); + // await increaseTime(duration.days(1)); + let tx = await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); + assert.equal(tx.logs[1].args._ticker, "LOG2", "Symbol should match with the registered symbol"); + assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token, `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); + assert.equal(tx.logs[0].args._owner, account_temp, `Token owner should be ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "LOG2", `Symbol should be LOG2`); + let symbolDetails = await I_STRProxied.getTickerDetails("LOG2"); + assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); + assert.equal(symbolDetails[3], "LOGAN2", `Name of the symbol should be LOGAN`); + }); + + }); + + describe("Test case for modifyTicker", async() => { + + it("Should add the custom ticker --failed because of bad owner", async() => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_temp}), + "tx revert -> failed beacause of bad owner0" + ); + }) + + it("Should add the custom ticker --fail ticker length should not be 0", async() => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, "", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_polymath}), + "tx revert -> failed beacause ticker length should not be 0" + ); + }) + + it("Should add the custom ticker --failed because time should not be 0", async() => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", 0, (latestTime() + duration.days(10)), false, {from: account_polymath}), + "tx revert -> failed because time should not be 0" + ); + }) + + it("Should add the custom ticker --failed because registeration date is greater than the expiryDate", async() => { + catchRevert( + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() - duration.minutes(10)), false, {from: account_polymath}), + "tx revert -> failed because registeration date is greater than the expiryDate" + ); + }) + + it("Should add the custom ticker --failed because owner should not be 0x", async() => { + catchRevert( + I_STRProxied.modifyTicker("0x000000000000000000000000000000000000000000", "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}), + "tx revert -> failed because owner should not be 0x" + ); + }) + + it("Should add the new custom ticker", async() => { + let tx = await I_STRProxied.modifyTicker(account_temp, "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "ETH", "Should be equal to ETH"); + }) + + it("Should change the details of the existing ticker", async() => { + let tx = await I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + assert.equal(tx.logs[0].args._owner, token_owner); + }); + + }); + + describe("Test cases for the transferTickerOwnership()", async() => { + + it("Should able to transfer the ticker ownership -- failed because token is not deployed having the same ticker", async() => { + catchRevert( + I_STRProxied.transferTickerOwnership(account_issuer, "ETH", {from: account_temp}), + "tx revert -> failed because token is not deployed having the same ticker" + ) + }) + + it("Should able to transfer the ticker ownership -- failed because new owner is 0x", async() => { + + await I_SecurityToken002.transferOwnership(account_temp, {from: token_owner}); + catchRevert( + I_STRProxied.transferTickerOwnership("0x00000000000000000000000000000000000000000", symbol2, {from: token_owner}), + "tx revert -> failed because new owner is 0x" + ) + }) + + it("Should able to transfer the ticker ownership -- failed because ticker is of zero length", async() => { + catchRevert( + I_STRProxied.transferTickerOwnership(account_temp, "", {from: token_owner}), + "tx revert -> failed because ticker is of zero length" + ); + }) + + it("Should able to transfer the ticker ownership", async() => { + let tx = await I_STRProxied.transferTickerOwnership(account_temp, symbol2, {from: token_owner, gas: 5000000 }); + assert.equal(tx.logs[0].args._newOwner, account_temp); + let symbolDetails = await I_STRProxied.getTickerDetails.call(symbol2); + assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); + assert.equal(symbolDetails[3], name2, `Name of the symbol should be ${name2}`); + }) + }) + + describe("Test case for the changeSecurityLaunchFee()", async() => { + + it("Should able to change the STLaunchFee-- failed because of bad owner", async() => { + catchRevert( + I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_temp}), + "tx revert -> failed because of bad owner" + ); + }); + + it("Should able to change the STLaunchFee-- failed because of putting the same fee", async() => { + catchRevert( + I_STRProxied.changeSecurityLaunchFee(initRegFee, {from: account_polymath}), + "tx revert -> failed because of putting the same fee" + ) + }); + + it("Should able to change the STLaunchFee", async() => { + let tx = await I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_polymath}); + assert.equal(tx.logs[0].args._newFee, web3.utils.toWei("500")); + let stLaunchFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3("stLaunchFee")); + assert.equal(stLaunchFee, web3.utils.toWei("500")); + }); + + }) + + describe("Test cases for the changeExpiryLimit()", async() => { + + it("Should able to change the ExpiryLimit-- failed because of bad owner", async() => { + catchRevert( + I_STRProxied.changeExpiryLimit(duration.days(15), {from: account_temp}), + "tx revert -> failed because of bad owner" + ) + }); + + it("Should able to change the ExpiryLimit-- failed because expirylimit is less than 1 day", async() => { + catchRevert( + I_STRProxied.changeExpiryLimit(duration.minutes(50), {from: account_polymath}), + "tx revert -> failed because expirylimit is less than 1 day" + ); + }); + + it("Should able to change the ExpiryLimit", async() => { + let tx = await I_STRProxied.changeExpiryLimit(duration.days(20), {from: account_polymath}); + assert.equal(tx.logs[0].args._newExpiry, duration.days(20)); + let expiry = await I_STRProxied.getUintValues(web3.utils.soliditySha3("expiryLimit")); + assert.equal(expiry, duration.days(20)); + }); + }) + + describe("Test cases for the changeTickerRegistrationFee()", async() => { + + it("Should able to change the TickerRegFee-- failed because of bad owner", async() => { + catchRevert( + I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("500"), {from: account_temp}), + "tx revert -> failed because of bad owner" + ) + }); + + it("Should able to change the TickerRegFee-- failed because of putting the same fee", async() => { + catchRevert( + I_STRProxied.changeTickerRegistrationFee(initRegFee, {from: account_polymath}), + "tx revert -> failed because of putting the same fee" + ); + }); + + it("Should able to change the TickerRegFee", async() => { + let tx = await I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("400"), {from: account_polymath}); + assert.equal(tx.logs[0].args._newFee, web3.utils.toWei("400")); + let tickerRegFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3("tickerRegFee")); + assert.equal(tickerRegFee, web3.utils.toWei("400")); + }); + + it("Should fail to register the ticker with the old fee", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + catchRevert( + I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }), + "tx revert -> failed because of ticker registeration fee gets change" + ); + }) + + it("Should register the ticker with the new fee", async() => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), token_owner); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); + assert.equal(tx.logs[0].args._ticker, "POLY", `Symbol should be POLY`); + }); + + it("Should fail to launch the securityToken with the old launch fee", async() => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + catchRevert( + I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }), + "tx revert -> failed because of old launch fee" + ) + }) + + it("Should launch the the securityToken", async() => { + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, "POLY", "SecurityToken doesn't get deployed"); + }); + }); + + describe("Test case for the update poly token", async() => { + + it("Should change the polytoken address -- failed because of bad owner", async() => { + catchRevert( + I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_temp}), + "tx revert -> failed because of bad owner" + ); + }) + + it("Should change the polytoken address -- failed because of 0x address", async() => { + catchRevert( + I_STRProxied.updatePolyTokenAddress("0x0000000000000000000000000000000000000000000", {from: account_polymath}), + "tx revert -> failed because 0x address" + ); + }) + + it("Should successfully change the polytoken address", async() => { + let _id = await takeSnapshot(); + await I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_polymath}); + assert.equal(await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")), dummy_token); + await revertToSnapshot(_id); + }); + }) + + describe("Test cases for getters", async() => { + + it("Should get the security token address", async() => { + let address = await I_STRProxied.getSecurityTokenAddress.call(symbol); + assert.equal(address, I_SecurityToken.address); + }); + + it("Should get the security token data", async() => { + let data = await I_STRProxied.getSecurityTokenData.call(I_SecurityToken.address); + assert.equal(data[0], symbol); + assert.equal(data[1], token_owner); + }); + + it("Should get the tickers by owner", async() => { + let tickersList = await I_STRProxied.getTickersByOwner.call(token_owner); + assert.equal(tickersList.length, 4); + let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); + console.log(tickersListArray); + assert.equal(tickersListArray.length, 3); + }); + + }); + + describe("Test case for the Removing the ticker", async() => { + + it("Should remove the ticker from the polymath ecosystem -- bad owner", async() => { + catchRevert( + I_STRProxied.removeTicker(symbol2, {from: account_investor1}), + "tx revert -> failed because msg.sender should be account_polymath" + ) + }) + + it("Should remove the ticker from the polymath ecosystem -- fail because ticker doesn't exist in the ecosystem", async() => { + catchRevert( + I_STRProxied.removeTicker("HOLA", {from: account_polymath}), + "tx revert -> failed because ticker doesn't exist in the polymath ecosystem" + ) + }) + + it("Should successfully remove the ticker from the polymath ecosystem", async() => { + let tx = await I_STRProxied.removeTicker(symbol2, {from: account_polymath}); + assert.equal(tx.logs[0].args._ticker, symbol2, "Ticker doesn't get deleted successfully"); + }); + }) + + describe(" Test cases of the registerTicker", async() => { + + it("Should register the ticker 1", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + let tx = await I_STRProxied.registerTicker(account_temp, "TOK1", "", { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK1", `Symbol should be TOK1`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + + it("Should register the ticker 2", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + let tx = await I_STRProxied.registerTicker(account_temp, "TOK2", "", { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK2", `Symbol should be TOK2`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + + it("Should register the ticker 3", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + let tx = await I_STRProxied.registerTicker(account_temp, "TOK3", "", { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK3", `Symbol should be TOK3`); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + + it("Should successfully remove the ticker 2", async() => { + let tx = await I_STRProxied.removeTicker("TOK2", {from: account_polymath}); + assert.equal(tx.logs[0].args._ticker, "TOK2", "Ticker doesn't get deleted successfully"); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }); + + it("Should modify ticker 1", async() => { + let tx = await I_STRProxied.modifyTicker(account_temp, "TOK1", "TOKEN 1", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK1", "Should be equal to TOK1"); + assert.equal(tx.logs[0].args._name, "TOKEN 1", "Should be equal to TOKEN 1"); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }) + + it("Should modify ticker 3", async() => { + let tx = await I_STRProxied.modifyTicker(account_temp, "TOK3", "TOKEN 3", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "TOK3", "Should be equal to TOK3"); + assert.equal(tx.logs[0].args._name, "TOKEN 3", "Should be equal to TOKEN 3"); + console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); + }) + + }); + describe("Test cases for IRegistry functionality", async() => { + + describe("Test cases for reclaiming funds", async() => { + + it("Should successfully reclaim POLY tokens", async() => { + I_PolyToken.transfer(I_STRProxied.address, web3.utils.toWei("1"), { from: token_owner }); + let bal1 = await I_PolyToken.balanceOf.call(account_polymath); + await I_STRProxied.reclaimERC20(I_PolyToken.address); + let bal2 = await I_PolyToken.balanceOf.call(account_polymath); + assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); + }); + + }); + + describe("Test cases for pausing the contract", async() => { + + it("Should fail to pause if msg.sender is not owner", async() => { + catchRevert( + I_STRProxied.pause({ from: account_temp }), + "tx revert -> msg.sender should be account_polymath" + ) + }); + + it("Should successfully pause the contract", async() => { + await I_STRProxied.pause({ from: account_polymath }); + let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); + assert.isOk(status); + }); + + it("Should fail to unpause if msg.sender is not owner", async() => { + catchRevert( + I_STRProxied.unpause({ from: account_temp }), + "tx revert -> msg.sender should be account_polymath" + ) + }); + + it("Should successfully unpause the contract", async() => { + await I_STRProxied.unpause({ from: account_polymath }); + let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); + assert.isNotOk(status); + }); + + }); - it('Should successfully remove the ticker 2', async () => { - let tx = await I_STRProxied.removeTicker('TOK2', { from: account_polymath }); - assert.equal(tx.logs[0].args._ticker, 'TOK2', "Ticker doesn't get deleted successfully"); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); - it('Should modify ticker 1', async () => { - let tx = await I_STRProxied.modifyTicker(account_temp, 'TOK1', 'TOKEN 1', latestTime(), latestTime() + duration.minutes(10), false, { - from: account_polymath - }); - assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, 'TOK1', 'Should be equal to TOK1'); - assert.equal(tx.logs[0].args._name, 'TOKEN 1', 'Should be equal to TOKEN 1'); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - - it('Should modify ticker 3', async () => { - let tx = await I_STRProxied.modifyTicker(account_temp, 'TOK3', 'TOKEN 3', latestTime(), latestTime() + duration.minutes(10), false, { - from: account_polymath - }); - assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); - assert.equal(tx.logs[0].args._ticker, 'TOK3', 'Should be equal to TOK3'); - assert.equal(tx.logs[0].args._name, 'TOKEN 3', 'Should be equal to TOKEN 3'); - console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }); - }); - describe('Test cases for IRegistry functionality', async () => { - describe('Test cases for reclaiming funds', async () => { - it('Should successfully reclaim POLY tokens', async () => { - I_PolyToken.transfer(I_STRProxied.address, web3.utils.toWei('1'), { from: token_owner }); - let bal1 = await I_PolyToken.balanceOf.call(account_polymath); - await I_STRProxied.reclaimERC20(I_PolyToken.address); - let bal2 = await I_PolyToken.balanceOf.call(account_polymath); - assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); - }); - }); - - describe('Test cases for pausing the contract', async () => { - it('Should fail to pause if msg.sender is not owner', async () => { - catchRevert(I_STRProxied.pause({ from: account_temp }), 'tx revert -> msg.sender should be account_polymath'); - }); - - it('Should successfully pause the contract', async () => { - await I_STRProxied.pause({ from: account_polymath }); - let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); - assert.isOk(status); - }); - - it('Should fail to unpause if msg.sender is not owner', async () => { - catchRevert(I_STRProxied.unpause({ from: account_temp }), 'tx revert -> msg.sender should be account_polymath'); - }); - - it('Should successfully unpause the contract', async () => { - await I_STRProxied.unpause({ from: account_polymath }); - let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3('paused')); - assert.isNotOk(status); - }); - }); - }); }); diff --git a/test/o_security_token.js b/test/o_security_token.js index 4fbec99e3..021154f8d 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); const CappedSTO = artifacts.require('./CappedSTO.sol'); const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); @@ -23,202 +23,210 @@ const TokenBurner = artifacts.require('./MockTokenBurner.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port -contract('SecurityToken', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_investor1; - let account_issuer; - let token_owner; - let account_investor2; - let account_investor3; - let account_affiliate1; - let account_affiliate2; - let account_fundsReceiver; - let account_delegate; - let account_temp; - let account_controller; - let address_zero = '0x0000000000000000000000000000000000000000'; - - let balanceOfReceiver; - // investor Details - let fromTime; - let toTime; - let expiryTime; - - let ID_snap; - const message = 'Transaction Should Fail!!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_CappedSTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_STRProxied; - let I_MRProxied; - let I_CappedSTO; - let I_PolyToken; - let I_TokenBurner; - let I_PolymathRegistry; - - // SecurityToken Details (Launched ST on the behalf of the issuer) - const name = 'Demo Token'; - const symbol = 'DET'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - let snap_Id; - // Module key - const permissionManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const budget = 0; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - - // delagate details - const delegateDetails = 'I am delegate ..'; - const TM_Perm = 'FLAGS'; - const TM_Perm_Whitelist = 'WHITELIST'; - - // Capped STO details - let startTime; - let endTime; - const cap = web3.utils.toWei('10000'); - const rate = 1000; - const fundRaiseType = [0]; - const cappedSTOSetupCost = web3.utils.toWei('20000', 'ether'); - const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_affiliate1 = accounts[2]; - account_affiliate2 = accounts[3]; - account_fundsReceiver = accounts[4]; - account_delegate = accounts[5]; - account_investor2 = accounts[6]; - account_investor3 = accounts[7]; - account_temp = accounts[8]; - account_investor1 = accounts[9]; - - token_owner = account_issuer; - account_controller = account_temp; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4 (a): Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - address_zero, - 'GeneralTransferManagerFactory contract was not deployed' - ); - - // STEP 4 (b): Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - address_zero, - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // STEP 4 (c): Deploy the CappedSTOFactory - - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - - assert.notEqual(I_CappedSTOFactory.address.valueOf(), address_zero, 'CappedSTOFactory contract was not deployed'); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // Step 6: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); +contract('SecurityToken', accounts => { - // Step 7: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + // Accounts Variable declaration + let account_polymath; + let account_investor1; + let account_issuer; + let token_owner; + let account_investor2; + let account_investor3; + let account_affiliate1; + let account_affiliate2; + let account_fundsReceiver; + let account_delegate; + let account_temp; + let account_controller; + let address_zero = "0x0000000000000000000000000000000000000000"; + + let balanceOfReceiver; + // investor Details + let fromTime; + let toTime; + let expiryTime; + + let ID_snap; + const message = "Transaction Should Fail!!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_CappedSTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_STRProxied; + let I_MRProxied; + let I_CappedSTO; + let I_PolyToken; + let I_TokenBurner; + let I_PolymathRegistry; + + // SecurityToken Details (Launched ST on the behalf of the issuer) + const name = "Demo Token"; + const symbol = "DET"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + let snap_Id; + // Module key + const permissionManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const budget = 0; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // delagate details + const delegateDetails = "I am delegate .."; + const TM_Perm = 'FLAGS'; + const TM_Perm_Whitelist = 'WHITELIST'; + + // Capped STO details + let startTime; + let endTime; + const cap = web3.utils.toWei("10000"); + const rate = 1000; + const fundRaiseType = [0]; + const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); + const maxCost = cappedSTOSetupCost; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_affiliate1 = accounts[2]; + account_affiliate2 = accounts[3]; + account_fundsReceiver = accounts[4]; + account_delegate = accounts[5]; + account_investor2 = accounts[6]; + account_investor3 = accounts[7]; + account_temp = accounts[8]; + account_investor1 = accounts[9]; + + token_owner = account_issuer; + account_controller = account_temp; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4 (a): Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + address_zero, + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 4 (b): Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + address_zero, + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 4 (c): Deploy the CappedSTOFactory + + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); + + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + address_zero, + "CappedSTOFactory contract was not deployed" + ); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // Step 6: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 7: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -234,781 +242,854 @@ contract('SecurityToken', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.toUtf8(log.args._name), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - - assert.notEqual(I_GeneralTransferManager.address.valueOf(), address_zero, 'GeneralTransferManager contract was not deployed'); - }); - - it('Should mint the tokens before attaching the STO -- fail only be called by the owner', async () => { - let fromTime = latestTime(); - let toTime = fromTime + duration.days(100); - let expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist(account_affiliate1, fromTime, toTime, expiryTime, true, { - from: token_owner, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_affiliate1, 'Failed in adding the investor in whitelist'); - await catchRevert(I_SecurityToken.mint(account_investor1, 100 * Math.pow(10, 18), { from: account_delegate })); - }); - - it('Should mint the tokens before attaching the STO', 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(), 100); - }); - - it('Should mint the multi tokens before attaching the STO -- fail only be called by the owner', async () => { - let fromTime = latestTime(); - let toTime = fromTime + duration.days(100); - let expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist(account_affiliate2, fromTime, toTime, expiryTime, true, { - from: token_owner, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_affiliate2, 'Failed in adding the investor in whitelist'); - await catchRevert( - I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [100 * Math.pow(10, 18), 110 * Math.pow(10, 18)], { - from: account_delegate, - gas: 500000 - }) - ); - }); - - it('Should mintMulti', async () => { - await catchRevert( - I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [100 * Math.pow(10, 18)], { from: token_owner, gas: 500000 }) - ); - }); - - it('Should mint the tokens for multiple afiliated investors before attaching the STO', 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(), 200); - let balance2 = await I_SecurityToken.balanceOf(account_affiliate2); - assert.equal(balance2.dividedBy(new BigNumber(10).pow(18)).toNumber(), 110); - }); - - it('Should finish the minting -- fail because feature is not activated', async () => { - await catchRevert(I_SecurityToken.freezeMinting({ from: token_owner })); - }); - - it('Should finish the minting -- fail to activate the feature because msg.sender is not polymath', async () => { - await catchRevert(I_FeatureRegistry.setFeatureStatus('freezeMintingAllowed', true, { from: token_owner })); - }); - - it('Should finish the minting -- successfully activate the feature', async () => { - await catchRevert(I_FeatureRegistry.setFeatureStatus('freezeMintingAllowed', false, { from: account_polymath })); - - 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 })); - - await catchRevert(I_FeatureRegistry.setFeatureStatus('freezeMintingAllowed', true, { from: account_polymath })); - }); - - it('Should finish the minting -- fail because msg.sender is not the owner', async () => { - await catchRevert(I_SecurityToken.freezeMinting({ from: account_temp })); - }); - - it('Should finish minting & restrict the further minting', async () => { - let id = await takeSnapshot(); - await I_SecurityToken.freezeMinting({ from: token_owner }); - - await catchRevert(I_SecurityToken.mint(account_affiliate1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); - 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); - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); - }); - - it('Should fail to attach the STO factory because max cost too small', 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 }); - - await catchRevert( - I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei('1000', 'ether'), 0, { from: token_owner }) - ); - }); - - 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._type, 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); - 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 }); - - await catchRevert(I_SecurityToken.mint(account_affiliate1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); - await revertToSnapshot(id); - }); - }); - - describe('Module related functions', async () => { - it('Should get the modules of the securityToken by index', 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], 3); - assert.equal(moduleData[5], 0); - assert.equal(moduleData[6], 0); - }); - - it('Should get the modules of the securityToken by index (not added into the security token yet)', async () => { - let moduleData = await I_SecurityToken.getModule.call(token_owner); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), ''); - assert.equal(moduleData[1], address_zero); - }); - - it('Should get the modules of the securityToken by name', async () => { - let moduleList = await I_SecurityToken.getModulesByName.call('CappedSTO'); - assert.isTrue(moduleList.length == 1, 'Only one STO'); - let moduleData = await I_SecurityToken.getModule.call(moduleList[0]); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'CappedSTO'); - assert.equal(moduleData[1], I_CappedSTO.address); - }); - - it('Should get the modules of the securityToken by name (not added into the security token yet)', async () => { - let moduleData = await I_SecurityToken.getModulesByName.call('GeneralPermissionManager'); - assert.isTrue(moduleData.length == 0, 'No Permission Manager'); - }); - - it('Should get the modules of the securityToken by name (not added into the security token yet)', async () => { - let moduleData = await I_SecurityToken.getModulesByName.call('CountTransferManager'); - assert.isTrue(moduleData.length == 0, 'No Permission Manager'); - }); - - it('Should fail in updating the token details', async () => { - await catchRevert(I_SecurityToken.updateTokenDetails('new token details', { from: account_delegate })); - }); - - it('Should update the token details', async () => { - let log = await I_SecurityToken.updateTokenDetails('new token details', { from: token_owner }); - assert.equal(log.logs[0].args._newDetails, 'new token details'); - }); - - it('Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner', async () => { - await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: account_temp })); - }); - - it('Should fail to remove the module - module not archived', async () => { - await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: token_owner })); - }); - - it('Should fail to remove the module - incorrect address', async () => { - await catchRevert(I_SecurityToken.removeModule(0, { from: token_owner })); - }); - - it('Should successfully remove the general transfer manager module from the securityToken', async () => { - let key = await takeSnapshot(); - await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }); - let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); - assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); - await revertToSnapshot(key); - }); - - it('Should verify the revertion of snapshot works properly', async () => { - let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'GeneralTransferManager'); - assert.equal(moduleData[1], I_GeneralTransferManager.address); - }); - - it('Should successfully archive the general transfer manager module from the securityToken', async () => { - let tx = await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); - assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); - let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'GeneralTransferManager'); - assert.equal(moduleData[1], I_GeneralTransferManager.address); - assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); - assert.equal(moduleData[3], true); - }); - - it('Should successfully mint tokens while GTM archived', async () => { - let key = await takeSnapshot(); - await I_SecurityToken.mint(1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 }); - let balance = await I_SecurityToken.balanceOf(1); - assert.equal(balance.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - await revertToSnapshot(key); - }); - - it('Should successfully unarchive the general transfer manager module from the securityToken', async () => { - let tx = await I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from: token_owner }); - assert.equal(tx.logs[0].args._type, transferManagerKey); - assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); - let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), 'GeneralTransferManager'); - assert.equal(moduleData[1], I_GeneralTransferManager.address); - assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); - assert.equal(moduleData[3], false); - }); - - it('Should fail to mint tokens while GTM unarchived', async () => { - await catchRevert(I_SecurityToken.mint(1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); - }); - - it('Should change the budget of the module - fail incorrect address', async () => { - await catchRevert(I_SecurityToken.changeModuleBudget(0, 100 * Math.pow(10, 18), { from: token_owner })); - }); - - it('Should change the budget of the module', async () => { - let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, 100 * Math.pow(10, 18), { from: token_owner }); - assert.equal(tx.logs[1].args._moduleType, stoKey); - assert.equal(tx.logs[1].args._module, I_CappedSTO.address); - assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - }); - }); - - describe('General Transfer manager Related test cases', async () => { - it('Should Buy the tokens', async () => { - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - // Add the Investor in to the whitelist - - fromTime = latestTime(); - toTime = fromTime + duration.days(100); - expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { - from: token_owner, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); - // Jump time - await increaseTime(5000); - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); - - assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - - assert.equal(await I_CappedSTO.investorCount.call(), 1); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - }); - - it('Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2', async () => { - await catchRevert(I_SecurityToken.transfer(account_investor2, 10 * Math.pow(10, 18), { from: account_investor1 })); - }); - - it('Should fail to provide the permission to the delegate to change the transfer bools', async () => { - // Add permission to the deletgate (A regesteration process) - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, '', 0, 0, { from: token_owner }); - let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); - I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); - }); - - it('Should provide the permission to the delegate to change the transfer bools', async () => { - // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { - from: token_owner - }); - - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); - }); - - it('Should fail to activate the bool allowAllTransfer', async () => { - await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from: account_temp })); - }); - - it('Should activate the bool allowAllTransfer', async () => { - ID_snap = await takeSnapshot(); - let tx = await I_GeneralTransferManager.changeAllowAllTransfers(true, { from: account_delegate }); - - assert.isTrue(tx.logs[0].args._allowAllTransfers, 'AllowTransfer variable is not successfully updated'); }); - it('Should fail to send tokens with the wrong granularity', async () => { - await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from: account_investor1 })); - }); - - it('Should adjust granularity', async () => { - await catchRevert(I_SecurityToken.changeGranularity(0, { from: token_owner })); - }); - - it('Should adjust granularity', async () => { - await I_SecurityToken.changeGranularity(Math.pow(10, 17), { from: token_owner }); - await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from: account_investor1, gas: 2500000 }); - await I_SecurityToken.transfer(account_investor1, Math.pow(10, 17), { from: accounts[7], gas: 2500000 }); - }); - - it('Should transfer from whitelist investor to non-whitelist investor in first tx and in 2nd tx non-whitelist to non-whitelist transfer', async () => { - await I_SecurityToken.transfer(accounts[7], 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 }); - - assert.equal( - (await I_SecurityToken.balanceOf(accounts[7])).dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10, - "Transfer doesn't take place properly" - ); - - await I_SecurityToken.transfer(account_temp, 5 * Math.pow(10, 18), { from: accounts[7], gas: 2500000 }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_temp)).dividedBy(new BigNumber(10).pow(18)).toNumber(), - 5, - "Transfer doesn't take place properly" - ); - await revertToSnapshot(ID_snap); - }); - - it('Should bool allowAllTransfer value is false', async () => { - assert.isFalse(await I_GeneralTransferManager.allowAllTransfers.call(), "reverting of snapshot doesn't works properly"); - }); - - it('Should change the bool allowAllWhitelistTransfers to true', async () => { - ID_snap = await takeSnapshot(); - let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from: account_delegate }); - - assert.isTrue(tx.logs[0].args._allowAllWhitelistTransfers, 'allowAllWhitelistTransfers variable is not successfully updated'); - }); - - it('Should transfer from whitelist investor1 to whitelist investor 2', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { - from: token_owner, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor2, 'Failed in adding the investor in whitelist'); - - await I_SecurityToken.transfer(account_investor2, 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10, - "Transfer doesn't take place properly" - ); - }); - - it('Should transfer from whitelist investor1 to whitelist investor 2 -- value = 0', async () => { - let tx = await I_SecurityToken.transfer(account_investor2, 0, { from: account_investor1, gas: 2500000 }); - assert.equal(tx.logs[0].args.value.toNumber(), 0); - }); - - it('Should transferFrom from one investor to other', async () => { - await I_SecurityToken.approve(account_investor1, 2 * Math.pow(10, 18), { from: account_investor2 }); - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { - from: token_owner, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor3, 'Failed in adding the investor in whitelist'); - let log = await I_SecurityToken.transferFrom(account_investor2, account_investor3, 2 * Math.pow(10, 18), { from: account_investor1 }); - assert.equal(log.logs[0].args.value.toNumber(), 2 * Math.pow(10, 18)); - }); - - it('Should Fail in trasferring from whitelist investor1 to non-whitelist investor', async () => { - await catchRevert(I_SecurityToken.transfer(account_temp, 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 })); - await revertToSnapshot(ID_snap); - }); - - 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 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 () => { - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist, true, { - from: token_owner - }); - - assert.isTrue( - await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist) - ); - }); - - it('Should add the investor in the whitelist by the delegate', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, fromTime, toTime, expiryTime, true, { - from: account_delegate, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_temp, 'Failed in adding the investor in whitelist'); - }); - - it('should account_temp successfully buy the token', async () => { - // 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.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2); - - assert.equal(await I_CappedSTO.investorCount.call(), 2); - - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); - }); - - it('STO should fail to mint tokens after minting is frozen', async () => { - let id = await takeSnapshot(); - await I_SecurityToken.freezeMinting({ from: token_owner }); - - await catchRevert( - web3.eth.sendTransaction({ - from: account_temp, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.toUtf8(log.args._name),"GeneralTransferManager"); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + assert.notEqual( + I_GeneralTransferManager.address.valueOf(), + address_zero, + "GeneralTransferManager contract was not deployed", + ); + + }); + + it("Should mint the tokens before attaching the STO -- fail only be called by the owner", async() => { + + let fromTime = latestTime(); + let toTime = fromTime + duration.days(100); + let expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_affiliate1, + fromTime, + toTime, + expiryTime, + true, + { + from: token_owner, + gas: 6000000 + }); + assert.equal(tx.logs[0].args._investor, account_affiliate1, "Failed in adding the investor in whitelist"); + await catchRevert(I_SecurityToken.mint(account_investor1, (100 * Math.pow(10, 18)), {from: account_delegate})); + }); + + it("Should mint the tokens before attaching the STO", 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(), 100); + }); + + it("Should mint the multi tokens before attaching the STO -- fail only be called by the owner", async() => { + + let fromTime = latestTime(); + let toTime = fromTime + duration.days(100); + let expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_affiliate2, + fromTime, + toTime, + expiryTime, + true, + { + from: token_owner, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_affiliate2, "Failed in adding the investor in whitelist"); + await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18)), (110 * Math.pow(10, 18))], {from: account_delegate, gas: 500000})); + }); + + it("Should mintMulti", async() => { + + await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18))], {from: token_owner, gas: 500000})); }) - ); - await revertToSnapshot(id); - }); - - it('Should remove investor from the whitelist by the delegate', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, 0, 0, 0, true, { - from: account_delegate, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_temp, 'Failed in removing the investor from whitelist'); - }); - - it('should account_temp fail in buying the token', async () => { - await catchRevert( - web3.eth.sendTransaction({ - from: account_temp, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') + it("Should mint the tokens for multiple afiliated investors before attaching the STO", 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(), 200); + let balance2 = await I_SecurityToken.balanceOf(account_affiliate2); + assert.equal(balance2.dividedBy(new BigNumber(10).pow(18)).toNumber(), 110); + }); + + it("Should finish the minting -- fail because feature is not activated", async() => { + + await catchRevert(I_SecurityToken.freezeMinting({from: token_owner})); + }); + + it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async() => { + + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: token_owner})); + }); + + it("Should finish the minting -- successfully activate the feature", async() => { + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", false, {from: account_polymath})); + + 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})); + + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_polymath})); + }); + + it("Should finish the minting -- fail because msg.sender is not the owner", async() => { + + await catchRevert(I_SecurityToken.freezeMinting({from: account_temp})); + }); + + it("Should finish minting & restrict the further minting", async() => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({from: token_owner}); + + await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); + 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); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); + + it("Should fail to attach the STO factory because max cost too small", 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}); + + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner })); + }); + + 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._type, 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); + 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}); + + await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); + await revertToSnapshot(id); + }); + + }); + + describe("Module related functions", async() => { + it("Should get the modules of the securityToken by index", 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], 3); + assert.equal(moduleData[5], 0); + assert.equal(moduleData[6], 0); + }); + + it("Should get the modules of the securityToken by index (not added into the security token yet)", async () => { + let moduleData = await I_SecurityToken.getModule.call(token_owner); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), ""); + assert.equal(moduleData[1], address_zero); + }); + + it("Should get the modules of the securityToken by name", async () => { + let moduleList = await I_SecurityToken.getModulesByName.call("CappedSTO"); + assert.isTrue(moduleList.length == 1, "Only one STO"); + let moduleData = await I_SecurityToken.getModule.call(moduleList[0]); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "CappedSTO"); + assert.equal(moduleData[1], I_CappedSTO.address); + }); + + it("Should get the modules of the securityToken by name (not added into the security token yet)", async () => { + let moduleData = await I_SecurityToken.getModulesByName.call("GeneralPermissionManager"); + assert.isTrue(moduleData.length == 0, "No Permission Manager"); + }); + + it("Should get the modules of the securityToken by name (not added into the security token yet)", async () => { + let moduleData = await I_SecurityToken.getModulesByName.call("CountTransferManager"); + assert.isTrue(moduleData.length == 0, "No Permission Manager"); + }); + + it("Should fail in updating the token details", async() => { + + await catchRevert(I_SecurityToken.updateTokenDetails("new token details", {from: account_delegate})); + }); + + it("Should update the token details", async() => { + let log = await I_SecurityToken.updateTokenDetails("new token details", {from: token_owner}); + assert.equal(log.logs[0].args._newDetails, "new token details"); + }); + + it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async() => { + + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp })); + }); + + it("Should fail to remove the module - module not archived", async() => { + + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner })); }) - ); - }); - - it('Should freeze the transfers', async () => { - let tx = await I_SecurityToken.freezeTransfers({ from: token_owner }); - assert.isTrue(tx.logs[0].args._status); - }); - - it('Should fail to freeze the transfers', async () => { - await catchRevert(I_SecurityToken.freezeTransfers({ from: token_owner })); - }); - - it('Should fail in buying to tokens', async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, fromTime, toTime, expiryTime, true, { - from: account_delegate, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_temp, 'Failed in adding the investor in whitelist'); - - await catchRevert( - web3.eth.sendTransaction({ - from: account_temp, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') + it("Should fail to remove the module - incorrect address", async() => { + + await catchRevert(I_SecurityToken.removeModule(0, { from : token_owner })); }) - ); - }); - it('Should fail in trasfering the tokens from one user to another', async () => { - await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from: token_owner }); - console.log(await I_SecurityToken.balanceOf(account_investor1)); - - await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_temp })); - }); + it("Should successfully remove the general transfer manager module from the securityToken", async() => { + let key = await takeSnapshot(); + await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); + let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner }); + assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); + await revertToSnapshot(key); + }); + + it("Should verify the revertion of snapshot works properly", async() => { + let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); + assert.equal(moduleData[1], I_GeneralTransferManager.address); + }); + + + it("Should successfully archive the general transfer manager module from the securityToken", async() => { + let tx = await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); + assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); + let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); + assert.equal(moduleData[1], I_GeneralTransferManager.address); + assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); + assert.equal(moduleData[3], true); + }); + + it("Should successfully mint tokens while GTM archived", async () => { + let key = await takeSnapshot(); + await I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + let balance = await I_SecurityToken.balanceOf(1); + assert.equal(balance.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + await revertToSnapshot(key); + }); + + it("Should successfully unarchive the general transfer manager module from the securityToken", async() => { + let tx = await I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from : token_owner }); + assert.equal(tx.logs[0].args._type, transferManagerKey); + assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); + let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); + assert.equal(moduleData[1], I_GeneralTransferManager.address); + assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); + assert.equal(moduleData[3], false); + }); + + it("Should fail to mint tokens while GTM unarchived", async () => { + + await catchRevert(I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); + + }); + + it("Should change the budget of the module - fail incorrect address", async() => { + + await catchRevert(I_SecurityToken.changeModuleBudget(0, (100 * Math.pow(10, 18)),{ from : token_owner})); + }); + + + it("Should change the budget of the module", async() => { + let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, (100 * Math.pow(10, 18)),{ from : token_owner}); + assert.equal(tx.logs[1].args._moduleType, stoKey); + assert.equal(tx.logs[1].args._module, I_CappedSTO.address); + assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + }); + + }); + + describe("General Transfer manager Related test cases", async () => { + + it("Should Buy the tokens", async() => { + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + // Add the Investor in to the whitelist + + fromTime = latestTime(); + toTime = fromTime + duration.days(100); + expiryTime = toTime + duration.days(100); + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + fromTime, + toTime, + expiryTime, + true, + { + from: token_owner, + gas: 6000000 + }); + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); + // Jump time + await increaseTime(5000); + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }); + + assert.equal( + (await I_CappedSTO.getRaised.call(0)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1 + ); + + assert.equal(await I_CappedSTO.investorCount.call(), 1); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + }); + + it("Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2", async() => { + + await catchRevert(I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1})); + }); + + it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { + + // Add permission to the deletgate (A regesteration process) + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: token_owner}); + let moduleData = await I_SecurityToken.modules(permissionManagerKey, 0); + I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); + }); + + it("Should provide the permission to the delegate to change the transfer bools", async () => { + // Add permission to the deletgate (A regesteration process) + await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: token_owner }); + + assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); + }); + + + it("Should fail to activate the bool allowAllTransfer", async() => { + + await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_temp })); + }); + + it("Should activate the bool allowAllTransfer", async() => { + ID_snap = await takeSnapshot(); + let tx = await I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_delegate }); + + assert.isTrue(tx.logs[0].args._allowAllTransfers, "AllowTransfer variable is not successfully updated"); + }); + + + it("Should fail to send tokens with the wrong granularity", async() => { + + await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1})); + }); + + it("Should adjust granularity", async() => { + + await catchRevert(I_SecurityToken.changeGranularity(0, {from: token_owner })); + }); + + it("Should adjust granularity", async() => { + + await I_SecurityToken.changeGranularity(Math.pow(10, 17), {from: token_owner }); + await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1, gas: 2500000 }); + await I_SecurityToken.transfer(account_investor1, Math.pow(10, 17), { from : accounts[7], gas: 2500000}); + }); + + it("Should transfer from whitelist investor to non-whitelist investor in first tx and in 2nd tx non-whitelist to non-whitelist transfer", async() => { + await I_SecurityToken.transfer(accounts[7], (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000}); + + assert.equal( + (await I_SecurityToken.balanceOf(accounts[7])) + .dividedBy(new BigNumber(10).pow(18)).toNumber(), + 10, + "Transfer doesn't take place properly" + ); + + await I_SecurityToken.transfer(account_temp, (5 * Math.pow(10, 18)), { from : accounts[7], gas: 2500000}); + + assert.equal( + (await I_SecurityToken.balanceOf(account_temp)) + .dividedBy(new BigNumber(10).pow(18)).toNumber(), + 5, + "Transfer doesn't take place properly" + ); + await revertToSnapshot(ID_snap); + }); + + it("Should bool allowAllTransfer value is false", async() => { + assert.isFalse(await I_GeneralTransferManager.allowAllTransfers.call(), "reverting of snapshot doesn't works properly"); + }); + + it("Should change the bool allowAllWhitelistTransfers to true", async () => { + ID_snap = await takeSnapshot(); + let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from : account_delegate }); + + assert.isTrue(tx.logs[0].args._allowAllWhitelistTransfers, "allowAllWhitelistTransfers variable is not successfully updated"); + }); + + it("Should transfer from whitelist investor1 to whitelist investor 2", async() => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + { + from: token_owner, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); + + await I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000}); + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)) + .dividedBy(new BigNumber(10).pow(18)).toNumber(), + 10, + "Transfer doesn't take place properly" + ); + }); + + it("Should transfer from whitelist investor1 to whitelist investor 2 -- value = 0", async() => { + let tx = await I_SecurityToken.transfer(account_investor2, 0, { from : account_investor1, gas: 2500000}); + assert.equal((tx.logs[0].args.value).toNumber(),0); + }); + + it("Should transferFrom from one investor to other", async() => { + await I_SecurityToken.approve(account_investor1, (2 * Math.pow(10, 18)),{from: account_investor2}); + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + fromTime, + toTime, + expiryTime, + true, + { + from: token_owner, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); + let log = await I_SecurityToken.transferFrom(account_investor2, account_investor3, (2 * Math.pow(10, 18)), {from: account_investor1}); + assert.equal((log.logs[0].args.value).toNumber(), (2 * Math.pow(10, 18))); + }); + + it("Should Fail in trasferring from whitelist investor1 to non-whitelist investor", async() => { + + await catchRevert(I_SecurityToken.transfer(account_temp, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000})); + await revertToSnapshot(ID_snap); + }); + + 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 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() => { + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist, true, { from: token_owner }); + + assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist)); + }); + + it("Should add the investor in the whitelist by the delegate", async() => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_temp, + fromTime, + toTime, + expiryTime, + true, + { + from: account_delegate, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); + }); + + it("should account_temp successfully buy the token", async() => { + // 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.getRaised.call(0)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 2 + ); + + assert.equal(await I_CappedSTO.investorCount.call(), 2); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + }); + + it("STO should fail to mint tokens after minting is frozen", async() => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({from: token_owner}); + + await catchRevert(web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + })); + await revertToSnapshot(id); + }); + + it("Should remove investor from the whitelist by the delegate", async() => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_temp, + 0, + 0, + 0, + true, + { + from: account_delegate, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_temp, "Failed in removing the investor from whitelist"); + }); + + it("should account_temp fail in buying the token", async() => { + + await catchRevert(web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + })); + }); + + it("Should freeze the transfers", async() => { + let tx = await I_SecurityToken.freezeTransfers({from: token_owner}); + assert.isTrue(tx.logs[0].args._status); + }); + + it("Should fail to freeze the transfers", async() => { + + await catchRevert(I_SecurityToken.freezeTransfers({from: token_owner})); + }); + + it("Should fail in buying to tokens", async() => { + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_temp, + fromTime, + toTime, + expiryTime, + true, + { + from: account_delegate, + gas: 6000000 + }); + + assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); + + + await catchRevert(web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + })); + }); + + it("Should fail in trasfering the tokens from one user to another", async() => { + await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); + console.log(await I_SecurityToken.balanceOf(account_investor1)); + + await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp})); + }); + + it("Should unfreeze all the transfers", async() => { + let tx = await I_SecurityToken.unfreezeTransfers({from: token_owner}); + assert.isFalse(tx.logs[0].args._status); + }); + + it("Should freeze the transfers", async() => { + + await catchRevert(I_SecurityToken.unfreezeTransfers({from: token_owner})); + }); + + it("Should able to transfers the tokens from one user to another", async() => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp}); + }); + + it("Should check that the list of investors is correct", async ()=> { + // Hardcode list of expected accounts based on transfers above + let investorsLength = await I_SecurityToken.getInvestorsLength(); + console.log(JSON.stringify(investorsLength)); + let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1, account_temp]; + assert.equal(investorsLength.toNumber(), 4); + console.log("Total Seen Investors: " + investorsLength.toNumber()); + for (let i = 0; i < investorsLength.toNumber(); i++) { + let investor = await I_SecurityToken.investors(i); + assert.equal(investor, expectedAccounts[i]); + } + }); + it("Should fail to set controller status because msg.sender not owner", async() => { + + await catchRevert(I_SecurityToken.setController(account_controller, {from: account_controller})); + }); + + it("Should successfully set controller", async() => { + let tx1 = await I_SecurityToken.setController(account_controller, {from: token_owner}); + + // check event + assert.equal(address_zero, tx1.logs[0].args._oldController, "Event not emitted as expected"); + assert.equal(account_controller, tx1.logs[0].args._newController, "Event not emitted as expected"); + + let tx2 = await I_SecurityToken.setController(address_zero, {from: token_owner}); + + // check event + assert.equal(account_controller, tx2.logs[0].args._oldController, "Event not emitted as expected"); + assert.equal(address_zero, tx2.logs[0].args._newController, "Event not emitted as expected"); + + let tx3 = await I_SecurityToken.setController(account_controller, {from: token_owner}); + + // check event + assert.equal(address_zero, tx3.logs[0].args._oldController, "Event not emitted as expected"); + assert.equal(account_controller, tx3.logs[0].args._newController, "Event not emitted as expected"); + + // check status + let controller = await I_SecurityToken.controller.call(); + assert.equal(account_controller, controller, "Status not set correctly"); + }); + + it("Should force burn the tokens - value too high", async ()=> { + + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); + let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", { from: account_controller })); + }); + it("Should force burn the tokens - wrong caller", async ()=> { + + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); + let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: token_owner })); + }); + + it("Should burn the tokens", async ()=> { + let currentInvestorCount = await I_SecurityToken.investorCount(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + // console.log(currentInvestorCount.toString(), currentBalance.toString()); + let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", { from: account_controller }); + // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); + assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); + let newInvestorCount = await I_SecurityToken.investorCount(); + // console.log(newInvestorCount.toString()); + assert.equal(newInvestorCount.toNumber() + 1, currentInvestorCount.toNumber(), "Investor count drops by one"); + }); + + it("Should prune investor length", async ()=> { + await I_SecurityToken.pruneInvestors(0, 10, {from: token_owner}); + // Hardcode list of expected accounts based on transfers above + let investorsLength = (await I_SecurityToken.getInvestorsLength.call()).toNumber(); + let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1]; + assert.equal(investorsLength, 3); + console.log("Total Seen Investors: " + investorsLength); + for (let i = 0; i < investorsLength; i++) { + let investor = await I_SecurityToken.investors(i); + assert.equal(investor, expectedAccounts[i]); + } + }); + + it("Should check the balance of investor at checkpoint", async() => { + + await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); + }); + + it("Should check the balance of investor at checkpoint", async() => { + let balance = await I_SecurityToken.balanceOfAt(account_investor1, 0); + assert.equal(balance.toNumber(), 0); + }); + }); + + describe("Withdraw Poly", async() => { + + it("Should successfully withdraw the poly", async() => { + + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: account_temp})); + }) + + it("Should successfully withdraw the poly", async() => { + let balanceBefore = await I_PolyToken.balanceOf(token_owner); + await I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: token_owner}); + let balanceAfter = await I_PolyToken.balanceOf(token_owner); + assert.equal((BigNumber(balanceAfter).sub(BigNumber(balanceBefore))).toNumber(), web3.utils.toWei("20000", "ether")); + }); + + it("Should successfully withdraw the poly", async() => { + + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), {from: token_owner})); + }); + }); + + describe("Force Transfer", async() => { + + it("Should fail to forceTransfer because not approved controller", async() => { + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_investor1})); + }); + + it("Should fail to forceTransfer because insufficient balance", async() => { + + await catchRevert(I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); + }); + + it("Should fail to forceTransfer because recipient is zero address", async() => { + + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); + }); + + it("Should successfully forceTransfer", async() => { + let sender = account_investor1; + let receiver = account_investor2; + + let start_investorCount = await I_SecurityToken.investorCount.call(); + let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); + let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); + + let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller}); + + let end_investorCount = await I_SecurityToken.investorCount.call(); + let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); + let end_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); + + assert.equal(start_investorCount.add(1).toNumber(), end_investorCount.toNumber(), "Investor count not changed"); + assert.equal(start_balInv1.sub(web3.utils.toWei("10", "ether")).toNumber(), end_balInv1.toNumber(), "Investor balance not changed"); + assert.equal(start_balInv2.add(web3.utils.toWei("10", "ether")).toNumber(), end_balInv2.toNumber(), "Investor balance not changed"); + console.log(tx.logs[0].args); + console.log(tx.logs[1].args); + assert.equal(account_controller, tx.logs[0].args._controller, "Event not emitted as expected"); + assert.equal(account_investor1, tx.logs[0].args._from, "Event not emitted as expected"); + assert.equal(account_investor2, tx.logs[0].args._to, "Event not emitted as expected"); + assert.equal(web3.utils.toWei("10", "ether"), tx.logs[0].args._value, "Event not emitted as expected"); + console.log(tx.logs[0].args._verifyTransfer); + assert.equal(false, tx.logs[0].args._verifyTransfer, "Event not emitted as expected"); + assert.equal("reason", web3.utils.hexToUtf8(tx.logs[0].args._data), "Event not emitted as expected"); + + assert.equal(account_investor1, tx.logs[1].args.from, "Event not emitted as expected"); + assert.equal(account_investor2, tx.logs[1].args.to, "Event not emitted as expected"); + assert.equal(web3.utils.toWei("10", "ether"), tx.logs[1].args.value, "Event not emitted as expected"); + }); + + it("Should fail to freeze controller functionality because not owner", async() => { + + await catchRevert(I_SecurityToken.disableController({from: account_investor1})); + }); + + it("Should fail to freeze controller functionality because disableControllerAllowed not activated", async() => { + + await catchRevert(I_SecurityToken.disableController({from: token_owner})); + }); + + it("Should successfully freeze controller functionality", async() => { + let tx1 = await I_FeatureRegistry.setFeatureStatus("disableControllerAllowed", true, {from: account_polymath}); + + // check event + assert.equal("disableControllerAllowed", tx1.logs[0].args._nameKey, "Event not emitted as expected"); + assert.equal(true, tx1.logs[0].args._newStatus, "Event not emitted as expected"); + + let tx2 = await I_SecurityToken.disableController({from: token_owner}); + + // check state + assert.equal(address_zero, await I_SecurityToken.controller.call(), "State not changed"); + assert.equal(true, await I_SecurityToken.controllerDisabled.call(), "State not changed"); + }); + + it("Should fail to freeze controller functionality because already frozen", async() => { + + await catchRevert(I_SecurityToken.disableController({from: token_owner})); + }); + + it("Should fail to set controller because controller functionality frozen", async() => { + + await catchRevert(I_SecurityToken.setController(account_controller, {from: token_owner})); + }); + + it("Should fail to forceTransfer because controller functionality frozen", async() => { + + await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "reason", {from: account_controller})); + }); + + }); - it('Should unfreeze all the transfers', async () => { - let tx = await I_SecurityToken.unfreezeTransfers({ from: token_owner }); - assert.isFalse(tx.logs[0].args._status); - }); - - it('Should freeze the transfers', async () => { - await catchRevert(I_SecurityToken.unfreezeTransfers({ from: token_owner })); - }); - - it('Should able to transfers the tokens from one user to another', async () => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_temp }); - }); - - it('Should check that the list of investors is correct', async () => { - // Hardcode list of expected accounts based on transfers above - let investorsLength = await I_SecurityToken.getInvestorsLength(); - console.log(JSON.stringify(investorsLength)); - let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1, account_temp]; - assert.equal(investorsLength.toNumber(), 4); - console.log('Total Seen Investors: ' + investorsLength.toNumber()); - for (let i = 0; i < investorsLength.toNumber(); i++) { - let investor = await I_SecurityToken.investors(i); - assert.equal(investor, expectedAccounts[i]); - } - }); - it('Should fail to set controller status because msg.sender not owner', async () => { - await catchRevert(I_SecurityToken.setController(account_controller, { from: account_controller })); - }); - - it('Should successfully set controller', async () => { - let tx1 = await I_SecurityToken.setController(account_controller, { from: token_owner }); - - // check event - assert.equal(address_zero, tx1.logs[0].args._oldController, 'Event not emitted as expected'); - assert.equal(account_controller, tx1.logs[0].args._newController, 'Event not emitted as expected'); - - let tx2 = await I_SecurityToken.setController(address_zero, { from: token_owner }); - - // check event - assert.equal(account_controller, tx2.logs[0].args._oldController, 'Event not emitted as expected'); - assert.equal(address_zero, tx2.logs[0].args._newController, 'Event not emitted as expected'); - - let tx3 = await I_SecurityToken.setController(account_controller, { from: token_owner }); - - // check event - assert.equal(address_zero, tx3.logs[0].args._oldController, 'Event not emitted as expected'); - assert.equal(account_controller, tx3.logs[0].args._newController, 'Event not emitted as expected'); - - // check status - let controller = await I_SecurityToken.controller.call(); - assert.equal(account_controller, controller, 'Status not set correctly'); - }); - - it('Should force burn the tokens - value too high', async () => { - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); - let currentInvestorCount = await I_SecurityToken.investorCount(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - await catchRevert( - I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei('500', 'ether'), '', { from: account_controller }) - ); - }); - it('Should force burn the tokens - wrong caller', async () => { - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); - let currentInvestorCount = await I_SecurityToken.investorCount(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance, '', { from: token_owner })); - }); - - it('Should burn the tokens', async () => { - let currentInvestorCount = await I_SecurityToken.investorCount(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - // console.log(currentInvestorCount.toString(), currentBalance.toString()); - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, '', { from: account_controller }); - // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); - assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); - let newInvestorCount = await I_SecurityToken.investorCount(); - // console.log(newInvestorCount.toString()); - assert.equal(newInvestorCount.toNumber() + 1, currentInvestorCount.toNumber(), 'Investor count drops by one'); - }); - - it('Should prune investor length', async () => { - await I_SecurityToken.pruneInvestors(0, 10, { from: token_owner }); - // Hardcode list of expected accounts based on transfers above - let investorsLength = (await I_SecurityToken.getInvestorsLength.call()).toNumber(); - let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1]; - assert.equal(investorsLength, 3); - console.log('Total Seen Investors: ' + investorsLength); - for (let i = 0; i < investorsLength; i++) { - let investor = await I_SecurityToken.investors(i); - assert.equal(investor, expectedAccounts[i]); - } - }); - - it('Should check the balance of investor at checkpoint', async () => { - await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); - }); - - it('Should check the balance of investor at checkpoint', async () => { - let balance = await I_SecurityToken.balanceOfAt(account_investor1, 0); - assert.equal(balance.toNumber(), 0); - }); - }); - - describe('Withdraw Poly', async () => { - it('Should successfully withdraw the poly', async () => { - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei('20000', 'ether'), { from: account_temp })); - }); - - it('Should successfully withdraw the poly', async () => { - let balanceBefore = await I_PolyToken.balanceOf(token_owner); - await I_SecurityToken.withdrawPoly(web3.utils.toWei('20000', 'ether'), { from: token_owner }); - let balanceAfter = await I_PolyToken.balanceOf(token_owner); - assert.equal( - BigNumber(balanceAfter) - .sub(BigNumber(balanceBefore)) - .toNumber(), - web3.utils.toWei('20000', 'ether') - ); - }); - - it('Should successfully withdraw the poly', async () => { - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei('10', 'ether'), { from: token_owner })); - }); - }); - - describe('Force Transfer', async () => { - it('Should fail to forceTransfer because not approved controller', async () => { - await catchRevert( - I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei('10', 'ether'), 'reason', { - from: account_investor1 - }) - ); - }); - - it('Should fail to forceTransfer because insufficient balance', async () => { - await catchRevert( - I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei('10', 'ether'), 'reason', { - from: account_controller - }) - ); - }); - - it('Should fail to forceTransfer because recipient is zero address', async () => { - await catchRevert( - I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei('10', 'ether'), 'reason', { - from: account_controller - }) - ); - }); - - it('Should successfully forceTransfer', async () => { - let sender = account_investor1; - let receiver = account_investor2; - - let start_investorCount = await I_SecurityToken.investorCount.call(); - let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); - let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); - - let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei('10', 'ether'), 'reason', { - from: account_controller - }); - - let end_investorCount = await I_SecurityToken.investorCount.call(); - let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); - let end_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); - - assert.equal(start_investorCount.add(1).toNumber(), end_investorCount.toNumber(), 'Investor count not changed'); - assert.equal(start_balInv1.sub(web3.utils.toWei('10', 'ether')).toNumber(), end_balInv1.toNumber(), 'Investor balance not changed'); - assert.equal(start_balInv2.add(web3.utils.toWei('10', 'ether')).toNumber(), end_balInv2.toNumber(), 'Investor balance not changed'); - console.log(tx.logs[0].args); - console.log(tx.logs[1].args); - assert.equal(account_controller, tx.logs[0].args._controller, 'Event not emitted as expected'); - assert.equal(account_investor1, tx.logs[0].args._from, 'Event not emitted as expected'); - assert.equal(account_investor2, tx.logs[0].args._to, 'Event not emitted as expected'); - assert.equal(web3.utils.toWei('10', 'ether'), tx.logs[0].args._value, 'Event not emitted as expected'); - console.log(tx.logs[0].args._verifyTransfer); - assert.equal(false, tx.logs[0].args._verifyTransfer, 'Event not emitted as expected'); - assert.equal('reason', web3.utils.hexToUtf8(tx.logs[0].args._data), 'Event not emitted as expected'); - - assert.equal(account_investor1, tx.logs[1].args.from, 'Event not emitted as expected'); - assert.equal(account_investor2, tx.logs[1].args.to, 'Event not emitted as expected'); - assert.equal(web3.utils.toWei('10', 'ether'), tx.logs[1].args.value, 'Event not emitted as expected'); - }); - - it('Should fail to freeze controller functionality because not owner', async () => { - await catchRevert(I_SecurityToken.disableController({ from: account_investor1 })); - }); - - it('Should fail to freeze controller functionality because disableControllerAllowed not activated', async () => { - await catchRevert(I_SecurityToken.disableController({ from: token_owner })); - }); - - it('Should successfully freeze controller functionality', async () => { - let tx1 = await I_FeatureRegistry.setFeatureStatus('disableControllerAllowed', true, { from: account_polymath }); - - // check event - assert.equal('disableControllerAllowed', tx1.logs[0].args._nameKey, 'Event not emitted as expected'); - assert.equal(true, tx1.logs[0].args._newStatus, 'Event not emitted as expected'); - - let tx2 = await I_SecurityToken.disableController({ from: token_owner }); - - // check state - assert.equal(address_zero, await I_SecurityToken.controller.call(), 'State not changed'); - assert.equal(true, await I_SecurityToken.controllerDisabled.call(), 'State not changed'); - }); - - it('Should fail to freeze controller functionality because already frozen', async () => { - await catchRevert(I_SecurityToken.disableController({ from: token_owner })); - }); - - it('Should fail to set controller because controller functionality frozen', async () => { - await catchRevert(I_SecurityToken.setController(account_controller, { from: token_owner })); - }); - - it('Should fail to forceTransfer because controller functionality frozen', async () => { - await catchRevert( - I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei('10', 'ether'), 'reason', { - from: account_controller - }) - ); - }); }); -}); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 407c59ec9..1584e7806 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); const USDTieredSTOProxyFactory = artifacts.require('./USDTieredSTOProxyFactory'); const USDTieredSTO = artifacts.require('./USDTieredSTO.sol'); @@ -24,88 +24,88 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port contract('USDTieredSTO', accounts => { - // Accounts Variable declaration - let POLYMATH; - let ISSUER; - let WALLET; - let RESERVEWALLET; - let INVESTOR1; - let INVESTOR2; - let INVESTOR3; - let INVESTOR4; - let ACCREDITED1; - let ACCREDITED2; - let NONACCREDITED1; - let NONACCREDITED2; - let ETH = 0; - let POLY = 1; - let DAI = 2; - - let MESSAGE = 'Transaction Should Fail!'; - const GAS_PRICE = 0; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_USDTieredSTOProxyFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_USDTieredSTOFactory; - let I_USDOracle; - let I_POLYOracle; - let I_STFactory; - let I_SecurityToken; - let I_STRProxied; - let I_MRProxied; - let I_USDTieredSTO_Array = []; - let I_PolyToken; - let I_DaiToken; - let I_PolymathRegistry; - - // SecurityToken Details for funds raise Type ETH - const NAME = 'Team'; - const SYMBOL = 'SAP'; - const TOKENDETAILS = 'This is equity type of issuance'; - const DECIMALS = 18; - - // Module key - const TMKEY = 2; - const STOKEY = 3; - - // Initial fee for ticker registry and security token registry - const REGFEE = web3.utils.toWei('250'); - const STOSetupCost = 0; - - // MockOracle USD prices - const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH - const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - // STO Configuration Arrays - let _startTime = []; - let _endTime = []; - let _ratePerTier = []; - let _ratePerTierDiscountPoly = []; - let _tokensPerTierTotal = []; - let _tokensPerTierDiscountPoly = []; - let _nonAccreditedLimitUSD = []; - let _minimumInvestmentUSD = []; - let _fundRaiseTypes = []; - let _wallet = []; - let _reserveWallet = []; - let _usdToken = []; - - /* function configure( + // Accounts Variable declaration + let POLYMATH; + let ISSUER; + let WALLET; + let RESERVEWALLET; + let INVESTOR1; + let INVESTOR2; + let INVESTOR3; + let INVESTOR4; + let ACCREDITED1; + let ACCREDITED2; + let NONACCREDITED1; + let NONACCREDITED2; + let ETH = 0; + let POLY = 1; + let DAI = 2; + + let MESSAGE = "Transaction Should Fail!"; + const GAS_PRICE = 0; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_USDTieredSTOProxyFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_USDTieredSTOFactory; + let I_USDOracle; + let I_POLYOracle; + let I_STFactory; + let I_SecurityToken; + let I_STRProxied; + let I_MRProxied; + let I_USDTieredSTO_Array = []; + let I_PolyToken; + let I_DaiToken; + let I_PolymathRegistry; + + // SecurityToken Details for funds raise Type ETH + const NAME = "Team"; + const SYMBOL = "SAP"; + const TOKENDETAILS = "This is equity type of issuance"; + const DECIMALS = 18; + + // Module key + const TMKEY = 2; + const STOKEY = 3; + + // Initial fee for ticker registry and security token registry + const REGFEE = web3.utils.toWei("250"); + const STOSetupCost = 0; + + // MockOracle USD prices + const USDETH = BigNumber(500).mul(10**18); // 500 USD/ETH + const USDPOLY = BigNumber(25).mul(10**16); // 0.25 USD/POLY + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + // STO Configuration Arrays + let _startTime = []; + let _endTime = []; + let _ratePerTier = []; + let _ratePerTierDiscountPoly = []; + let _tokensPerTierTotal = []; + let _tokensPerTierDiscountPoly = []; + let _nonAccreditedLimitUSD = []; + let _minimumInvestmentUSD = []; + let _fundRaiseTypes = []; + let _wallet = []; + let _reserveWallet = []; + let _usdToken = []; + + /* function configure( uint256 _startTime, uint256 _endTime, uint256[] _ratePerTier, @@ -119,222 +119,210 @@ contract('USDTieredSTO', accounts => { address _reserveWallet, address _usdToken ) */ - const functionSignature = { - name: 'configure', - type: 'function', - inputs: [ - { - type: 'uint256', - name: '_startTime' - }, - { - type: 'uint256', - name: '_endTime' - }, - { - type: 'uint256[]', - name: '_ratePerTier' - }, - { - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - }, - { - type: 'uint256[]', - name: '_tokensPerTier' - }, - { - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - }, - { - type: 'uint256', - name: '_nonAccreditedLimitUSD' - }, - { - type: 'uint256', - name: '_minimumInvestmentUSD' - }, - { - type: 'uint8[]', - name: '_fundRaiseTypes' - }, - { - type: 'address', - name: '_wallet' - }, - { - type: 'address', - name: '_reserveWallet' - }, - { - type: 'address', - name: '_usdToken' - } - ] - }; - - async function convert(_stoID, _tier, _discount, _currencyFrom, _currencyTo, _amount) { - let USDTOKEN; - if (_discount) USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTierDiscountPoly.call(_tier); - else USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTier.call(_tier); - if (_currencyFrom == 'TOKEN') { - let tokenToUSD = _amount - .div(10 ** 18) - .mul(USDTOKEN.div(10 ** 18)) - .mul(10 ** 18); // TOKEN * USD/TOKEN = USD - if (_currencyTo == 'USD') return tokenToUSD; - if (_currencyTo == 'ETH') { - return await I_USDTieredSTO_Array[_stoID].convertFromUSD(ETH, tokenToUSD); - } else if (_currencyTo == 'POLY') { - return await I_USDTieredSTO_Array[_stoID].convertFromUSD(POLY, tokenToUSD); - } + const functionSignature = { + name: 'configure', + type: 'function', + inputs: [{ + type: 'uint256', + name: '_startTime' + },{ + type: 'uint256', + name: '_endTime' + },{ + type: 'uint256[]', + name: '_ratePerTier' + },{ + type: 'uint256[]', + name: '_ratePerTierDiscountPoly' + },{ + type: 'uint256[]', + name: '_tokensPerTier' + },{ + type: 'uint256[]', + name: '_tokensPerTierDiscountPoly' + },{ + type: 'uint256', + name: '_nonAccreditedLimitUSD' + },{ + type: 'uint256', + name: '_minimumInvestmentUSD' + },{ + type: 'uint8[]', + name: '_fundRaiseTypes' + },{ + type: 'address', + name: '_wallet' + },{ + type: 'address', + name: '_reserveWallet' + },{ + type: 'address', + name: '_usdToken' + }] + }; + + async function convert(_stoID, _tier, _discount, _currencyFrom, _currencyTo, _amount) { + let USDTOKEN; + if (_discount) + USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTierDiscountPoly.call(_tier); + else + USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTier.call(_tier); + if (_currencyFrom == "TOKEN") { + let tokenToUSD = _amount.div(10**18).mul(USDTOKEN.div(10**18)).mul(10**18); // TOKEN * USD/TOKEN = USD + if (_currencyTo == "USD") + return tokenToUSD; + if (_currencyTo == "ETH") { + return await I_USDTieredSTO_Array[_stoID].convertFromUSD(ETH, tokenToUSD); + } else if (_currencyTo == "POLY") { + return await I_USDTieredSTO_Array[_stoID].convertFromUSD(POLY, tokenToUSD); + } + } + if (_currencyFrom == "USD") { + if (_currencyTo == "TOKEN") + return _amount.div(USDTOKEN).mul(10**18); // USD / USD/TOKEN = TOKEN + if (_currencyTo == "ETH" || _currencyTo == "POLY") + return await I_USDTieredSTO_Array[_stoID].convertFromUSD((_currencyTo == "ETH" ? ETH : POLY), _amount); + } + if (_currencyFrom == "ETH" || _currencyFrom == "POLY") { + let ethToUSD = await I_USDTieredSTO_Array[_stoID].convertToUSD((_currencyTo == "ETH" ? ETH : POLY), _amount); + if (_currencyTo == "USD") + return ethToUSD; + if (_currencyTo == "TOKEN") + return ethToUSD.div(USDTOKEN).mul(10**18); // USD / USD/TOKEN = TOKEN + } + return 0; } - if (_currencyFrom == 'USD') { - if (_currencyTo == 'TOKEN') return _amount.div(USDTOKEN).mul(10 ** 18); // USD / USD/TOKEN = TOKEN - if (_currencyTo == 'ETH' || _currencyTo == 'POLY') - return await I_USDTieredSTO_Array[_stoID].convertFromUSD(_currencyTo == 'ETH' ? ETH : POLY, _amount); - } - if (_currencyFrom == 'ETH' || _currencyFrom == 'POLY') { - let ethToUSD = await I_USDTieredSTO_Array[_stoID].convertToUSD(_currencyTo == 'ETH' ? ETH : POLY, _amount); - if (_currencyTo == 'USD') return ethToUSD; - if (_currencyTo == 'TOKEN') return ethToUSD.div(USDTOKEN).mul(10 ** 18); // USD / USD/TOKEN = TOKEN - } - return 0; - } - - before(async () => { - // Accounts setup - POLYMATH = accounts[0]; - ISSUER = accounts[1]; - WALLET = accounts[2]; - RESERVEWALLET = WALLET; - ACCREDITED1 = accounts[3]; - ACCREDITED2 = accounts[4]; - NONACCREDITED1 = accounts[5]; - NONACCREDITED2 = accounts[6]; - INVESTOR1 = accounts[7]; - INVESTOR2 = accounts[8]; - INVESTOR3 = accounts[9]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: POLYMATH - }); - // STEP 3: Deploy the ModuleRegistry + before(async() => { + // Accounts setup + POLYMATH = accounts[0]; + ISSUER = accounts[1]; + WALLET = accounts[2]; + RESERVEWALLET = WALLET; + ACCREDITED1 = accounts[3]; + ACCREDITED2 = accounts[4]; + NONACCREDITED1 = accounts[5]; + NONACCREDITED2 = accounts[6]; + INVESTOR1 = accounts[7]; + INVESTOR2 = accounts[8]; + INVESTOR3 = accounts[9]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + I_DaiToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), ISSUER); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: POLYMATH + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 3: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + // STEP 4: Deploy the GeneralDelegateManagerFactory - // STEP 3: Deploy the GeneralTransferManagerFactory + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + // STEP 5: Deploy the proxy + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - // STEP 4: Deploy the GeneralDelegateManagerFactory + // STEP 6: Deploy the USDTieredSTOFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: ISSUER }); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "USDTieredSTOFactory contract was not deployed" + ); - // STEP 5: Deploy the proxy - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); + // Step 8: Deploy the STFactory contract - // STEP 6: Deploy the USDTieredSTOFactory + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 9: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: POLYMATH}); + await I_MRProxied.updateFromRegistry({from: POLYMATH}); - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { - from: ISSUER - }); - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'USDTieredSTOFactory contract was not deployed' - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - REGFEE, - REGFEE, - I_PolyToken.address, - POLYMATH - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); - await I_MRProxied.updateFromRegistry({ from: POLYMATH }); - - // STEP 7: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); - - // 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 }); - await I_PolymathRegistry.changeAddress('PolyUsdOracle', I_POLYOracle.address, { from: POLYMATH }); - - // Printing all the contract addresses - console.log(` + // STEP 7: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + + // 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 }); + await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -352,2485 +340,1703 @@ contract('USDTieredSTO', accounts => { USDTieredSTOProxyFactory: ${I_USDTieredSTOProxyFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from: ISSUER }); - assert.equal(tx.logs[0].args._owner, ISSUER); - assert.equal(tx.logs[0].args._ticker, SYMBOL); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); - assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), TMKEY); - assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(TMKEY, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - }); - - describe('Test sto deployment', async () => { - it('Should successfully attach the first STO module to the security token', async () => { - let stoId = 0; // No discount - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] - _ratePerTierDiscountPoly.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] - _tokensPerTierTotal.push([BigNumber(100000000).mul(BigNumber(10 ** 18)), BigNumber(200000000).mul(BigNumber(10 ** 18))]); // [ 100m Token, 200m Token ] - _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0)]); // [ 0, 0 ] - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); // 10k USD - _minimumInvestmentUSD.push(BigNumber(5 * 10 ** 18)); // 5 USD - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - - assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], 'Incorrect _startTime in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], 'Incorrect _endTime in config'); - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), - _ratePerTier[stoId][i].toNumber(), - 'Incorrect _ratePerTier in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), - _ratePerTierDiscountPoly[stoId][i].toNumber(), - 'Incorrect _ratePerTierDiscountPoly in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), - _tokensPerTierTotal[stoId][i].toNumber(), - 'Incorrect _tokensPerTierTotal in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), - _tokensPerTierDiscountPoly[stoId][i].toNumber(), - 'Incorrect _tokensPerTierDiscountPoly in config' - ); - } - assert.equal( - (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), - _nonAccreditedLimitUSD[stoId].toNumber(), - 'Incorrect _nonAccreditedLimitUSD in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), - _minimumInvestmentUSD[stoId].toNumber(), - 'Incorrect _minimumInvestmentUSD in config' - ); - assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], 'Incorrect _wallet in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(), _reserveWallet[stoId], 'Incorrect _reserveWallet in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(), _usdToken[stoId], 'Incorrect _usdToken in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, 'Incorrect number of tiers'); - assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, 'Incorrect number of permissions'); - }); - - it('Should successfully attach the second STO module to the security token', async () => { - let stoId = 1; // No discount - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([ - BigNumber(10 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16) - ]); - _ratePerTierDiscountPoly.push([ - BigNumber(10 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16), - BigNumber(15 * 10 ** 16) - ]); - _tokensPerTierTotal.push([ - BigNumber(5 * 10 ** 18), - BigNumber(10 * 10 ** 18), - BigNumber(10 * 10 ** 18), - BigNumber(10 * 10 ** 18), - BigNumber(10 * 10 ** 18), - BigNumber(50 * 10 ** 18) - ]); - _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0)]); - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); - _minimumInvestmentUSD.push(BigNumber(0)); - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - - assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], 'Incorrect _startTime in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], 'Incorrect _endTime in config'); - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), - _ratePerTier[stoId][i].toNumber(), - 'Incorrect _ratePerTier in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), - _ratePerTierDiscountPoly[stoId][i].toNumber(), - 'Incorrect _ratePerTierDiscountPoly in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), - _tokensPerTierTotal[stoId][i].toNumber(), - 'Incorrect _tokensPerTierTotal in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), - _tokensPerTierDiscountPoly[stoId][i].toNumber(), - 'Incorrect _tokensPerTierDiscountPoly in config' - ); - } - assert.equal( - (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), - _nonAccreditedLimitUSD[stoId].toNumber(), - 'Incorrect _nonAccreditedLimitUSD in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), - _minimumInvestmentUSD[stoId].toNumber(), - 'Incorrect _minimumInvestmentUSD in config' - ); - assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], 'Incorrect _wallet in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(), _reserveWallet[stoId], 'Incorrect _reserveWallet in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(), _usdToken[stoId], 'Incorrect _usdToken in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, 'Incorrect number of tiers'); - assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, 'Incorrect number of permissions'); - }); - - it('Should successfully attach the third STO module to the security token', async () => { - let stoId = 2; // Poly discount - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(1 * 10 ** 18), BigNumber(1.5 * 10 ** 18)]); // [ 1 USD/Token, 1.5 USD/Token ] - _ratePerTierDiscountPoly.push([BigNumber(0.5 * 10 ** 18), BigNumber(1 * 10 ** 18)]); // [ 0.5 USD/Token, 1.5 USD/Token ] - _tokensPerTierTotal.push([BigNumber(100 * 10 ** 18), BigNumber(50 * 10 ** 18)]); // [ 100 Token, 50 Token ] - _tokensPerTierDiscountPoly.push([BigNumber(100 * 10 ** 18), BigNumber(25 * 10 ** 18)]); // [ 100 Token, 25 Token ] - _nonAccreditedLimitUSD.push(BigNumber(25 * 10 ** 18)); // [ 25 USD ] - _minimumInvestmentUSD.push(BigNumber(5)); - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - }); - - it('Should successfully attach the fourth STO module to the security token', async () => { - let stoId = 3; - - _startTime.push(latestTime() + duration.days(0.1)); - _endTime.push(_startTime[stoId] + duration.days(0.1)); - _ratePerTier.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); - _ratePerTierDiscountPoly.push([BigNumber(10 * 10 ** 16), BigNumber(12 * 10 ** 16)]); - _tokensPerTierTotal.push([BigNumber(100 * 10 ** 18), BigNumber(200 * 10 ** 18)]); - _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(50 * 10 ** 18)]); - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); - _minimumInvestmentUSD.push(BigNumber(0)); - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - }); - - it('Should fail because rates and tier array of different length', async () => { - let stoId = 0; - - let ratePerTier = [10]; - let ratePerTierDiscountPoly = [10]; - let tokensPerTierTotal = [10]; - let tokensPerTierDiscountPoly = [10]; - let config = [ - [ - _startTime[stoId], - _endTime[stoId], - ratePerTier, - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ], - [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - ratePerTierDiscountPoly, - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ], - [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - tokensPerTierTotal, - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ], - [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - tokensPerTierDiscountPoly, - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ] - ]; - for (var i = 0; i < config.length; i++) { - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - } - }); - - it('Should fail because rate of token should be greater than 0', async () => { - let stoId = 0; - - let ratePerTier = [BigNumber(10 * 10 ** 16), BigNumber(0)]; - let config = [ - _startTime[stoId], - _endTime[stoId], - ratePerTier, - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it('Should fail because Zero address is not permitted for wallet', async () => { - let stoId = 0; - - let wallet = '0x0000000000000000000000000000000000000000'; - let config = [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - wallet, - _reserveWallet[stoId], - _usdToken[stoId] - ]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it('Should fail because Zero address is not permitted for reserveWallet', async () => { - let stoId = 0; - - let reserveWallet = '0x0000000000000000000000000000000000000000'; - let config = [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - reserveWallet - ]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it('Should fail because end time before start time', async () => { - let stoId = 0; - - let startTime = latestTime() + duration.days(35); - let endTime = latestTime() + duration.days(1); - let config = [ - startTime, - endTime, - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - - it('Should fail because start time is in the past', async () => { - let stoId = 0; - - let startTime = latestTime() - duration.days(35); - let endTime = startTime + duration.days(50); - let config = [ - startTime, - endTime, - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); - }); - }); - - describe('Test modifying configuration', async () => { - it('Should successfully change config before startTime - funding', async () => { - let stoId = 3; - await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), true, "STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), false, "STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyFunding([1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), false, "STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), true, "STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyFunding([0, 1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), true, "STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), true, "STO Configuration doesn't set as expected"); - }); - - it('Should successfully change config before startTime - limits and tiers, times, addresses', async () => { - let stoId = 3; - - await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1 * 10 ** 18), BigNumber(15 * 10 ** 18), { from: ISSUER }); - assert.equal( - (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), - BigNumber(15 * 10 ** 18).toNumber(), - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), - BigNumber(1 * 10 ** 18).toNumber(), - "STO Configuration doesn't set as expected" - ); - - await I_USDTieredSTO_Array[stoId].modifyTiers( - [BigNumber(15 * 10 ** 18)], - [BigNumber(13 * 10 ** 18)], - [BigNumber(15 * 10 ** 20)], - [BigNumber(15 * 10 ** 20)], - { from: ISSUER } - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(), - BigNumber(15 * 10 ** 18).toNumber(), - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(), - BigNumber(13 * 10 ** 18).toNumber(), - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0), - BigNumber(15 * 10 ** 20).toNumber(), - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0), - BigNumber(15 * 10 ** 20).toNumber(), - "STO Configuration doesn't set as expected" - ); - - let tempTime1 = latestTime() + duration.days(0.1); - let tempTime2 = latestTime() + duration.days(0.2); - - await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), tempTime1, "STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), tempTime2, "STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyAddresses( - '0x0000000000000000000000000400000000000000', - '0x0000000000000000000003000000000000000000', - '0x0000000000000000000000000000000000000000', - { from: ISSUER } - ); - assert.equal( - await I_USDTieredSTO_Array[stoId].wallet.call(), - '0x0000000000000000000000000400000000000000', - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_USDTieredSTO_Array[stoId].reserveWallet.call(), - '0x0000000000000000000003000000000000000000', - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_USDTieredSTO_Array[stoId].usdToken.call(), - '0x0000000000000000000000000000000000000000', - "STO Configuration doesn't set as expected" - ); - }); - - it('Should fail to change config after endTime', async () => { - let stoId = 3; - - let snapId = await takeSnapshot(); - await increaseTime(duration.days(1)); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0, 1], { from: ISSUER })); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15 * 10 ** 18), BigNumber(1 * 10 ** 18), { from: ISSUER })); - - await catchRevert( - I_USDTieredSTO_Array[stoId].modifyTiers( - [BigNumber(15 * 10 ** 18)], - [BigNumber(13 * 10 ** 18)], - [BigNumber(15 * 10 ** 20)], - [BigNumber(15 * 10 ** 20)], - { from: ISSUER } - ) - ); - - let tempTime1 = latestTime(); - let tempTime2 = latestTime() + duration.days(3); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER })); - - await catchRevert( - I_USDTieredSTO_Array[stoId].modifyAddresses( - '0x0000000000000000000000000400000000000000', - '0x0000000000000000000003000000000000000000', - I_DaiToken.address, - { from: ISSUER } - ) - ); - - await revertToSnapshot(snapId); - }); - }); - - describe('Test buying failure conditions', async () => { - it('should fail if before STO start time', async () => { - let stoId = 0; - let snapId = await takeSnapshot(); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, 'STO is not showing correct status'); - - // Whitelist - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let whitelisted = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); - - // // Advance time to after STO start - // await increaseTime(duration.days(3)); - - // Set as accredited - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); - - // NONACCREDITED ETH - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - }); - - it('should fail and revert despite oracle price change when NONACCREDITED cap reached', async () => { - let stoId = 0; - let tierId; - - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - - let investment_USD = BigNumber(web3.utils.toWei('50')); // USD - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); - - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); - - it('should successfully buy across tiers for NONACCREDITED ETH', async () => { - let stoId = 1; - let startTier = 0; - let endTier = 1; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); - - let delta_Token = BigNumber(5).mul(10 ** 18); - let ethTier0 = await convert(stoId, startTier, false, 'TOKEN', 'ETH', delta_Token); - let ethTier1 = await convert(stoId, endTier, false, 'TOKEN', 'ETH', delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { - from: NONACCREDITED1, - value: investment_ETH, - gasPrice: GAS_PRICE - }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal - .sub(gasCost1) - .sub(investment_ETH) - .toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); - assert.equal( - final_WalletETHBal.toNumber(), - init_WalletETHBal.add(investment_ETH).toNumber(), - 'Wallet ETH Balance not changed as expected' - ); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); - }); - - it('should successfully buy across tiers for NONACCREDITED POLY', async () => { - let stoId = 1; - let startTier = 1; - let endTier = 2; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); - - let delta_Token = BigNumber(5).mul(10 ** 18); // Token - let polyTier0 = await convert(stoId, startTier, false, 'TOKEN', 'POLY', delta_Token); - let polyTier1 = await convert(stoId, endTier, false, 'TOKEN', 'POLY', delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { - from: NONACCREDITED1, - gasPrice: GAS_PRICE - }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.sub(investment_POLY).toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.add(investment_POLY).toNumber(), - 'Wallet POLY Balance not changed as expected' - ); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); - }); - - it('should successfully buy across tiers for ACCREDITED ETH', async () => { - let stoId = 1; - let startTier = 2; - let endTier = 3; - - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); - - let delta_Token = BigNumber(5).mul(10 ** 18); // Token - let ethTier0 = await convert(stoId, startTier, false, 'TOKEN', 'ETH', delta_Token); - let ethTier1 = await convert(stoId, endTier, false, 'TOKEN', 'ETH', delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { - from: ACCREDITED1, - value: investment_ETH, - gasPrice: GAS_PRICE - }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal - .sub(gasCost1) - .sub(investment_ETH) - .toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); - assert.equal( - final_WalletETHBal.toNumber(), - init_WalletETHBal.add(investment_ETH).toNumber(), - 'Wallet ETH Balance not changed as expected' - ); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); - }); - - it('should successfully buy across tiers for ACCREDITED DAI', async () => { - let stoId = 1; - let startTier = 3; - let endTier = 4; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); - - let delta_Token = BigNumber(5).mul(10 ** 18); // Token - let daiTier0 = await convert(stoId, startTier, false, 'TOKEN', 'USD', delta_Token); - let daiTier1 = await convert(stoId, endTier, false, 'TOKEN', 'USD', delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_DAI = daiTier0.add(daiTier1); - - await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithUSD: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); - assert.equal( - final_InvestorDAIBal.toNumber(), - init_InvestorDAIBal.sub(investment_DAI).toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); - assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), 'Raised DAI not changed as expected'); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); - assert.equal( - final_WalletDAIBal.toNumber(), - init_WalletDAIBal.add(investment_DAI).toNumber(), - 'Wallet POLY Balance not changed as expected' - ); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); - }); - - it('should successfully buy across tiers for ACCREDITED POLY', async () => { - let stoId = 1; - let startTier = 4; - let endTier = 5; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); - - let delta_Token = BigNumber(5).mul(10 ** 18); // Token - let polyTier0 = await convert(stoId, startTier, false, 'TOKEN', 'POLY', delta_Token); - let polyTier1 = await convert(stoId, endTier, false, 'TOKEN', 'POLY', delta_Token); - - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.sub(investment_POLY).toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.add(investment_POLY).toNumber(), - 'Wallet POLY Balance not changed as expected' - ); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); }); - it('should buy out the rest of the sto', async () => { - let stoId = 1; - let tierId = 5; - - let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); - console.log(minted.toNumber() + ':' + _tokensPerTierTotal[stoId][tierId]); - let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); - console.log(investment_Token.toNumber()); - let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - let tx = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - console.log(' Gas buyWithETH: '.grey + tx.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - // assert.equal((await I_USDTieredSTO_Array[1].getTokensMinted()).toNumber(), _tokensPerTierTotal[1].reduce((a, b) => a + b, 0).toNumber(), "STO Token Sold not changed as expected"); - }); - - it('should fail and revert when all tiers sold out', async () => { - let stoId = 1; - let tierId = 4; - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); - let investment_DAI = investment_USD; - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - - await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, 'STO is not showing correct status'); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Buy with DAI NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Buy with ETH ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - - // Buy with DAI ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - }); - - it('should fail and revert when all tiers sold out despite oracle price change', async () => { - let stoId = 1; - let tierId = 4; - - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - - let investment_USD = BigNumber(web3.utils.toWei('50')); // USD - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); - await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: ACCREDITED1 }); - - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) - ); + describe("Generate the SecurityToken", async() => { - // Buy with POLY NONACCREDITED + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from : ISSUER }); + assert.equal(tx.logs[0].args._owner, ISSUER); + assert.equal(tx.logs[0].args._ticker, SYMBOL); + }); - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); + assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); - // Buy with ETH ACCREDITED + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) - ); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - // Buy with POLY ACCREDITED + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), TMKEY); + assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + }); - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }) - ); + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(TMKEY, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Buy with ETH ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); - }); - - describe('Buy Tokens with POLY discount', async () => { - it('should successfully buy using fallback at tier 0 for NONACCREDITED1', async () => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await web3.eth.sendTransaction({ - from: NONACCREDITED1, - to: I_USDTieredSTO_Array[stoId].address, - value: investment_ETH, - gasPrice: GAS_PRICE, - gas: 1000000 - }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(' Gas fallback purchase: '.grey + tx1.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal - .sub(gasCost1) - .sub(investment_ETH) - .toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), 'Raised USD not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); - assert.equal( - final_WalletETHBal.toNumber(), - init_WalletETHBal.add(investment_ETH).toNumber(), - 'Wallet ETH Balance not changed as expected' - ); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); - - // Additional checks on getters - assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, 'Investor count not changed as expected'); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), - investment_Token.toNumber(), - 'getTokensSold not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), - investment_Token.toNumber(), - 'getTokensMinted not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), - investment_Token.toNumber(), - 'getTokensSoldForETH not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), - 0, - 'getTokensSoldForPOLY not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), - investment_USD.toNumber(), - 'investorInvestedUSD not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), - investment_ETH.toNumber(), - 'investorInvestedETH not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), - 0, - 'investorInvestedPOLY not changed as expected' - ); - }); - - it('should successfully buy using buyWithETH at tier 0 for NONACCREDITED1', async () => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { - from: NONACCREDITED1, - value: investment_ETH, - gasPrice: GAS_PRICE - }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal - .sub(gasCost1) - .sub(investment_ETH) - .toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); - assert.equal( - final_WalletETHBal.toNumber(), - init_WalletETHBal.add(investment_ETH).toNumber(), - 'Wallet ETH Balance not changed as expected' - ); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); - }); - - it('should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1', async () => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, true, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', investment_Token); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { - from: NONACCREDITED1, - gasPrice: GAS_PRICE - }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.sub(investment_POLY).toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.add(investment_POLY).toNumber(), - 'Wallet POLY Balance not changed as expected' - ); + }); }); - it('should successfully buy using fallback at tier 0 for ACCREDITED1', async () => { - let stoId = 2; - let tierId = 0; - - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await web3.eth.sendTransaction({ - from: ACCREDITED1, - to: I_USDTieredSTO_Array[stoId].address, - value: investment_ETH, - gasPrice: GAS_PRICE, - gas: 1000000 - }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(' Gas fallback purchase: '.grey + tx1.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal - .sub(gasCost1) - .sub(investment_ETH) - .toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); - assert.equal( - final_WalletETHBal.toNumber(), - init_WalletETHBal.add(investment_ETH).toNumber(), - 'Wallet ETH Balance not changed as expected' - ); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); + describe("Test sto deployment", async() => { + + it("Should successfully attach the first STO module to the security token", async () => { + let stoId = 0; // No discount + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(15*10**16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] + _tokensPerTierTotal.push([BigNumber(100000000).mul(BigNumber(10**18)), BigNumber(200000000).mul(BigNumber(10**18))]); // [ 100m Token, 200m Token ] + _tokensPerTierDiscountPoly.push([BigNumber(0),BigNumber(0)]); // [ 0, 0 ] + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); // 10k USD + _minimumInvestmentUSD.push(BigNumber(5*10**18)); // 5 USD + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + + assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); + } + assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].usdToken.call()), _usdToken[stoId], "Incorrect _usdToken in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].getNumberOfTiers()), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); + assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); + }); + + it("Should successfully attach the second STO module to the security token", async () => { + let stoId = 1; // No discount + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16)]); + _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16)]); + _tokensPerTierTotal.push([BigNumber(5*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(50*10**18)]); + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0)]); + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); + _minimumInvestmentUSD.push(BigNumber(0)); + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + + assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); + } + assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].usdToken.call()), _usdToken[stoId], "Incorrect _usdToken in config"); + assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); + assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); + }); + + it("Should successfully attach the third STO module to the security token", async () => { + let stoId = 2; // Poly discount + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([BigNumber(1*10**18), BigNumber(1.5*10**18)]); // [ 1 USD/Token, 1.5 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(0.5*10**18), BigNumber(1*10**18)]); // [ 0.5 USD/Token, 1.5 USD/Token ] + _tokensPerTierTotal.push([BigNumber(100*10**18), BigNumber(50*10**18)]); // [ 100 Token, 50 Token ] + _tokensPerTierDiscountPoly.push([BigNumber(100*10**18),BigNumber(25*10**18)]); // [ 100 Token, 25 Token ] + _nonAccreditedLimitUSD.push(BigNumber(25*10**18)); // [ 25 USD ] + _minimumInvestmentUSD.push(BigNumber(5)); + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address) + + let config = [ + _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + }); + + it("Should successfully attach the fourth STO module to the security token", async () => { + let stoId = 3; + + _startTime.push(latestTime()+ duration.days(0.1)); + _endTime.push(_startTime[stoId] + duration.days(0.1)); + _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16)]); + _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(12*10**16)]); + _tokensPerTierTotal.push([BigNumber(100*10**18), BigNumber(200*10**18)]); + _tokensPerTierDiscountPoly.push([BigNumber(0),BigNumber(50*10**18)]); + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); + _minimumInvestmentUSD.push(BigNumber(0)); + _fundRaiseTypes.push([0, 1, 2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + }); + + it("Should fail because rates and tier array of different length", async() => { + let stoId = 0; + + let ratePerTier = [10]; + let ratePerTierDiscountPoly = [10]; + let tokensPerTierTotal = [10]; + let tokensPerTierDiscountPoly = [10]; + let config = [ + [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], + [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], ratePerTierDiscountPoly, _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], + [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], tokensPerTierTotal, _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], + [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], tokensPerTierDiscountPoly, _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]] + ]; + for (var i = 0; i < config.length; i++) { + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + } + }); + + it("Should fail because rate of token should be greater than 0", async() => { + let stoId = 0; + + let ratePerTier = [BigNumber(10*10**16), BigNumber(0)]; + let config = [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it("Should fail because Zero address is not permitted for wallet", async() => { + let stoId = 0; + + let wallet = "0x0000000000000000000000000000000000000000"; + let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], wallet, _reserveWallet[stoId], _usdToken[stoId]]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it("Should fail because Zero address is not permitted for reserveWallet", async() => { + let stoId = 0; + + let reserveWallet = "0x0000000000000000000000000000000000000000"; + let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], reserveWallet]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it("Should fail because end time before start time", async() => { + let stoId = 0; + + let startTime = latestTime() + duration.days(35); + let endTime = latestTime() + duration.days(1); + let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); + + it("Should fail because start time is in the past", async() => { + let stoId = 0; + + let startTime = latestTime() - duration.days(35); + let endTime = startTime + duration.days(50); + let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); + }); }); - it('should successfully buy using buyWithETH at tier 0 for ACCREDITED1', async () => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { - from: ACCREDITED1, - value: investment_ETH, - gasPrice: GAS_PRICE - }); - let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(' Gas buyWithETH: '.grey + tx1.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal - .sub(gasCost1) - .sub(investment_ETH) - .toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), 'Investor POLY Balance not changed as expected'); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), 'Raised POLY not changed as expected'); - assert.equal( - final_WalletETHBal.toNumber(), - init_WalletETHBal.add(investment_ETH).toNumber(), - 'Wallet ETH Balance not changed as expected' - ); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), 'Wallet POLY Balance not changed as expected'); - }); + describe("Test modifying configuration", async() => { - it('should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1', async () => { - let stoId = 2; - let tierId = 0; - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, true, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', investment_Token); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - - // Additional checks on getters - let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_getTokensMinted = await I_USDTieredSTO_Array[stoId].getTokensMinted(); - let init_getTokensSoldForETH = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH); - let init_getTokensSoldForPOLY = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY); - let init_investorInvestedUSD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1); - let init_investorInvestedETH = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH); - let init_investorInvestedPOLY = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.sub(investment_POLY).toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.add(investment_POLY).toNumber(), - 'Wallet POLY Balance not changed as expected' - ); - - // Additional checks on getters - assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, 'Investor count not changed as expected'); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), - init_getTokensSold.add(investment_Token).toNumber(), - 'getTokensSold not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), - init_getTokensMinted.add(investment_Token).toNumber(), - 'getTokensMinted not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), - init_getTokensSoldForETH.toNumber(), - 'getTokensSoldForETH not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), - init_getTokensSoldForPOLY.add(investment_Token).toNumber(), - 'getTokensSoldForPOLY not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), - init_investorInvestedUSD.add(investment_USD).toNumber(), - 'investorInvestedUSD not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), - init_investorInvestedETH.toNumber(), - 'investorInvestedETH not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), - init_investorInvestedPOLY.add(investment_POLY).toNumber(), - 'investorInvestedPOLY not changed as expected' - ); - }); + it("Should successfully change config before startTime - funding", async() => { + let stoId = 3; + await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),false,"STO Configuration doesn't set as expected"); - it('should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap', async () => { - let stoId = 2; - let tierId = 0; - - let investment_USD = _nonAccreditedLimitUSD[stoId]; - let investment_Token = await convert(stoId, tierId, true, 'USD', 'TOKEN', investment_USD); - let investment_ETH = await convert(stoId, tierId, true, 'USD', 'ETH', investment_USD); - let investment_POLY = await convert(stoId, tierId, true, 'USD', 'POLY', investment_USD); - - let refund_USD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); - let refund_Token = await convert(stoId, tierId, true, 'USD', 'TOKEN', refund_USD); - let refund_ETH = await convert(stoId, tierId, true, 'USD', 'ETH', refund_USD); - let refund_POLY = await convert(stoId, tierId, true, 'USD', 'POLY', refund_USD); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { - from: NONACCREDITED1, - gasPrice: GAS_PRICE - }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal( - final_TokenSupply.toNumber(), - init_TokenSupply - .add(investment_Token) - .sub(refund_Token) - .toNumber(), - 'Token Supply not changed as expected' - ); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal - .add(investment_Token) - .sub(refund_Token) - .toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal - .sub(investment_POLY) - .add(refund_POLY) - .toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold - .add(investment_Token) - .sub(refund_Token) - .toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal( - final_RaisedPOLY.toNumber(), - init_RaisedPOLY - .add(investment_POLY) - .sub(refund_POLY) - .toNumber(), - 'Raised POLY not changed as expected' - ); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal - .add(investment_POLY) - .sub(refund_POLY) - .toNumber(), - 'Wallet POLY Balance not changed as expected' - ); - }); + await I_USDTieredSTO_Array[stoId].modifyFunding([1], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),false,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - it('should fail and revert when NONACCREDITED cap reached', async () => { - let stoId = 2; - let tierId = 0; + await I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, true, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', investment_Token); - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + }); - // Buy with ETH NONACCREDITED + it("Should successfully change config before startTime - limits and tiers, times, addresses", async() => { + let stoId = 3; - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - }); + await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1*10**18), BigNumber(15*10**18), { from: ISSUER }); + assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(),BigNumber(1*10**18).toNumber(),"STO Configuration doesn't set as expected"); - it('should fail and revert despite oracle price change when NONACCREDITED cap reached', async () => { - let stoId = 2; - let tierId = 0; + await I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER }); + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(),BigNumber(13*10**18).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY + let tempTime1 = latestTime() + duration.days(0.1); + let tempTime2 = latestTime() + duration.days(0.2); - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); + await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(),tempTime1,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(),tempTime2,"STO Configuration doesn't set as expected"); - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + await I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", "0x0000000000000000000000000000000000000000", { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(),"0x0000000000000000000000000400000000000000","STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(),"0x0000000000000000000003000000000000000000","STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(),"0x0000000000000000000000000000000000000000","STO Configuration doesn't set as expected"); + }); - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); + it("Should fail to change config after endTime", async() => { + let stoId = 3; - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + let snapId = await takeSnapshot(); + await increaseTime(duration.days(1)); - // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER })); - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) - ); + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15*10**18), BigNumber(1*10**18), { from: ISSUER })); - // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER })); - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); + let tempTime1 = latestTime(); + let tempTime2 = latestTime() + duration.days(3); - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER })); - // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", I_DaiToken.address, { from: ISSUER })); - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + await revertToSnapshot(snapId); + }); }); - it('should successfully buy across tiers for POLY', async () => { - let stoId = 2; - let startTier = 0; - let endTier = 1; - - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, 'currentTier not changed as expected'); - - let delta_Token = BigNumber(5).mul(10 ** 18); // Token - let polyTier0 = await convert(stoId, startTier, true, 'TOKEN', 'POLY', delta_Token); - let polyTier1 = await convert(stoId, endTier, true, 'TOKEN', 'POLY', delta_Token); - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH - - let tokensRemaining = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)).sub( - await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier) - ); - let prep_Token = tokensRemaining.sub(delta_Token); - let prep_POLY = await convert(stoId, startTier, true, 'TOKEN', 'POLY', prep_Token); - - await I_PolyToken.getTokens(prep_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, prep_POLY, { from: ACCREDITED1 }); - let tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, prep_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - console.log(' Gas buyWithPOLY: '.grey + tx.receipt.gasUsed.toString().grey); - - let Tier0Token = await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier); - let Tier0Minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier); - assert.equal(Tier0Minted.toNumber(), Tier0Token.sub(delta_Token).toNumber()); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - - // Process investment - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.sub(investment_POLY).toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.add(investment_POLY).toNumber(), - 'Wallet POLY Balance not changed as expected' - ); - - // Additional Checks - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, 'currentTier not changed as expected'); + describe("Test buying failure conditions", async() => { + + it("should fail if before STO start time", async() => { + let stoId = 0; + let snapId = await takeSnapshot(); + + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + + // Whitelist + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + + // // Advance time to after STO start + // await increaseTime(duration.days(3)); + + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + // Prep for investments + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + + // NONACCREDITED ETH + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + }); + + it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { + let stoId = 0; + let tierId; + + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + + let investment_USD = BigNumber(web3.utils.toWei('50')); // USD + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); + + it("should successfully buy across tiers for NONACCREDITED ETH", async() => { + let stoId = 1; + let startTier = 0; + let endTier = 1; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + + let delta_Token = BigNumber(5).mul(10**18); + let ethTier0 = await convert(stoId, startTier, false, "TOKEN", "ETH", delta_Token); + let ethTier1 = await convert(stoId, endTier, false, "TOKEN", "ETH", delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); + }); + + it("should successfully buy across tiers for NONACCREDITED POLY", async() => { + let stoId = 1; + let startTier = 1; + let endTier = 2; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + + let delta_Token = BigNumber(5).mul(10**18); // Token + let polyTier0 = await convert(stoId, startTier, false, "TOKEN", "POLY", delta_Token); + let polyTier1 = await convert(stoId, endTier, false, "TOKEN", "POLY", delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); + }); + + it("should successfully buy across tiers for ACCREDITED ETH", async() => { + let stoId = 1; + let startTier = 2; + let endTier = 3; + + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + + let delta_Token = BigNumber(5).mul(10**18); // Token + let ethTier0 = await convert(stoId, startTier, false, "TOKEN", "ETH", delta_Token); + let ethTier1 = await convert(stoId, endTier, false, "TOKEN", "ETH", delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); + }); + + it("should successfully buy across tiers for ACCREDITED DAI", async() => { + + let stoId = 1; + let startTier = 3; + let endTier = 4; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + + let delta_Token = BigNumber(5).mul(10**18); // Token + let daiTier0 = await convert(stoId, startTier, false, "TOKEN", "USD", delta_Token); + let daiTier1 = await convert(stoId, endTier, false, "TOKEN", "USD", delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_DAI = daiTier0.add(daiTier1); + + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithUSD: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_InvestorDAIBal = await I_DaiToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), "Raised DAI not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); + + }); + + it("should successfully buy across tiers for ACCREDITED POLY", async() => { + let stoId = 1; + let startTier = 4; + let endTier = 5; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + + let delta_Token = BigNumber(5).mul(10**18); // Token + let polyTier0 = await convert(stoId, startTier, false, "TOKEN", "POLY", delta_Token); + let polyTier1 = await convert(stoId, endTier, false, "TOKEN", "POLY", delta_Token); + + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); + }); + + it("should buy out the rest of the sto", async() => { + let stoId = 1; + let tierId = 5; + + let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); + console.log(minted.toNumber() + ":"+ _tokensPerTierTotal[stoId][tierId]); + let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); + console.log(investment_Token.toNumber()); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + let tx = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + console.log(" Gas buyWithETH: ".grey+tx.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + // assert.equal((await I_USDTieredSTO_Array[1].getTokensMinted()).toNumber(), _tokensPerTierTotal[1].reduce((a, b) => a + b, 0).toNumber(), "STO Token Sold not changed as expected"); + }); + + it("should fail and revert when all tiers sold out", async() => { + let stoId = 1; + let tierId = 4; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + let investment_DAI = investment_USD; + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with DAI NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with ETH ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with DAI ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + }); + + it("should fail and revert when all tiers sold out despite oracle price change", async() => { + let stoId = 1; + let tierId = 4; + + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + + let investment_USD = BigNumber(web3.utils.toWei('50')); // USD + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: ACCREDITED1}); + + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with ETH ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with ETH ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); }); - it('should successfully buy across the discount cap', async () => { - let stoId = 2; - let tierId = 1; - - let discount_Token = BigNumber(20).mul(10 ** 18); - let discount_POLY = await convert(stoId, tierId, true, 'TOKEN', 'POLY', discount_Token); - - let regular_Token = BigNumber(10).mul(10 ** 18); - let regular_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', regular_Token); - - let investment_Token = discount_Token.add(regular_Token); - let investment_POLY = discount_POLY.add(regular_POLY); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost2).toNumber(), - 'Investor ETH Balance not changed as expected' - ); - assert.equal( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.sub(investment_POLY).toNumber(), - 'Investor POLY Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); - assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), 'STO ETH Balance not changed as expected'); - assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), 'STO POLY Balance not changed as expected'); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), 'Raised ETH not changed as expected'); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), 'Raised POLY not changed as expected'); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), 'Wallet ETH Balance not changed as expected'); - assert.equal( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.add(investment_POLY).toNumber(), - 'Wallet POLY Balance not changed as expected' - ); + describe("Buy Tokens with POLY discount", async() => { + + it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async() => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await web3.eth.sendTransaction({ from: NONACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); + console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), "Raised USD not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional checks on getters + assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, "Investor count not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), investment_Token.toNumber(), "getTokensSold not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), investment_Token.toNumber(), "getTokensMinted not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), investment_Token.toNumber(), "getTokensSoldForETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), 0, "getTokensSoldForPOLY not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), investment_USD.toNumber(), "investorInvestedUSD not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), investment_ETH.toNumber(), "investorInvestedETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), 0, "investorInvestedPOLY not changed as expected"); + }); + + it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async() => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async() => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using fallback at tier 0 for ACCREDITED1", async() => { + let stoId = 2; + let tierId = 0; + + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await web3.eth.sendTransaction({ from: ACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); + console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async() => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async() => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + // Additional checks on getters + let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_getTokensMinted = await I_USDTieredSTO_Array[stoId].getTokensMinted(); + let init_getTokensSoldForETH = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH); + let init_getTokensSoldForPOLY = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY); + let init_investorInvestedUSD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1); + let init_investorInvestedETH = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH); + let init_investorInvestedPOLY = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional checks on getters + assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, "Investor count not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), init_getTokensSold.add(investment_Token).toNumber(), "getTokensSold not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), init_getTokensMinted.add(investment_Token).toNumber(), "getTokensMinted not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), init_getTokensSoldForETH.toNumber(), "getTokensSoldForETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), init_getTokensSoldForPOLY.add(investment_Token).toNumber(), "getTokensSoldForPOLY not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), init_investorInvestedUSD.add(investment_USD).toNumber(), "investorInvestedUSD not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), init_investorInvestedETH.toNumber(), "investorInvestedETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), init_investorInvestedPOLY.add(investment_POLY).toNumber(), "investorInvestedPOLY not changed as expected"); + }); + + it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async() => { + let stoId = 2; + let tierId = 0; + + let investment_USD = _nonAccreditedLimitUSD[stoId]; + let investment_Token = await convert(stoId, tierId, true, "USD", "TOKEN", investment_USD); + let investment_ETH = await convert(stoId, tierId, true, "USD", "ETH", investment_USD); + let investment_POLY = await convert(stoId, tierId, true, "USD", "POLY", investment_USD); + + let refund_USD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); + let refund_Token = await convert(stoId, tierId, true, "USD", "TOKEN", refund_USD); + let refund_ETH = await convert(stoId, tierId, true, "USD", "ETH", refund_USD); + let refund_POLY = await convert(stoId, tierId, true, "USD", "POLY", refund_USD); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).add(refund_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).sub(refund_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).sub(refund_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should fail and revert when NONACCREDITED cap reached", async() => { + let stoId = 2; + let tierId = 0; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1, gasPrice: GAS_PRICE}); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + }); + + it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { + let stoId = 2; + let tierId = 0; + + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); + + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); + + it("should successfully buy across tiers for POLY", async() => { + let stoId = 2; + let startTier = 0; + let endTier = 1; + + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + + let delta_Token = BigNumber(5).mul(10**18); // Token + let polyTier0 = await convert(stoId, startTier, true, "TOKEN", "POLY", delta_Token); + let polyTier1 = await convert(stoId, endTier, true, "TOKEN", "POLY", delta_Token); + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + + let tokensRemaining = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier)); + let prep_Token = tokensRemaining.sub(delta_Token); + let prep_POLY = await convert(stoId, startTier, true, "TOKEN", "POLY", prep_Token); + + await I_PolyToken.getTokens(prep_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, prep_POLY, {from: ACCREDITED1}); + let tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, prep_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + console.log(" Gas buyWithPOLY: ".grey+tx.receipt.gasUsed.toString().grey); + + let Tier0Token = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)); + let Tier0Minted = (await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier)); + assert.equal(Tier0Minted.toNumber(), Tier0Token.sub(delta_Token).toNumber()); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + // Process investment + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional Checks + assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); + }); + + it("should successfully buy across the discount cap", async() => { + let stoId = 2; + let tierId = 1; + + let discount_Token = BigNumber(20).mul(10**18); + let discount_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", discount_Token); + + let regular_Token = BigNumber(10).mul(10**18); + let regular_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", regular_Token); + + let investment_Token = discount_Token.add(regular_Token); + let investment_POLY = discount_POLY.add(regular_POLY); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should buy out the rest of the sto", async() => { + let stoId = 2; + let tierId = 1; + + let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); + let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + }); + + it("should fail and revert when all tiers sold out", async() => { + let stoId = 2; + let tierId = 1; + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with ETH ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + }); + + it("should fail and revert when all tiers sold out despite oracle price change", async() => { + let stoId = 2; + let tierId = 1; + + // set new exchange rates + let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + + let investment_Token = BigNumber(5).mul(10**18); + let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); + + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + + await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: ACCREDITED1}); + + // Change exchange rates up + await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with ETH ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + // Change exchange rates down + await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); + + // Buy with ETH NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + // Buy with ETH ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + // Buy with POLY ACCREDITED + + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); }); - it('should buy out the rest of the sto', async () => { - let stoId = 2; - let tierId = 1; - - let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); - let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); - let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); - - await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(' Gas buyWithPOLY: '.grey + tx2.receipt.gasUsed.toString().grey); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), 'Token Supply not changed as expected'); - assert.equal( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - 'Investor Token Balance not changed as expected' - ); - assert.equal( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - 'STO Token Sold not changed as expected' - ); + describe("Test getter functions", async() => { + + describe("Generic", async() => { + + it("should get the right number of investors", async() => { + assert.equal((await I_USDTieredSTO_Array[0].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[0].investorCount()).toNumber(), "Investor count not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[1].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[1].investorCount()).toNumber(), "Investor count not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[2].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[2].investorCount()).toNumber(), "Investor count not changed as expected"); + }); + + it("should get the right amounts invested", async() => { + assert.equal((await I_USDTieredSTO_Array[0].fundsRaised.call(ETH)).toNumber(), (await I_USDTieredSTO_Array[0].getRaised(0)).toNumber(), "getRaisedEther not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[0].fundsRaised.call(POLY)).toNumber(), (await I_USDTieredSTO_Array[0].getRaised(1)).toNumber(), "getRaisedPOLY not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[0].fundsRaisedUSD.call()).toNumber(), (await I_USDTieredSTO_Array[0].fundsRaisedUSD()).toNumber(), "fundsRaisedUSD not changed as expected"); + }); + }); + + describe("convertToUSD", async() => { + + it("should reset exchange rates", async() => { + // Reset exchange rates + await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); + await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); + }); + + it("should get the right conversion for ETH to USD", async() => { + // 20 ETH to 10000 USD + let ethInWei = BigNumber(web3.utils.toWei('20', 'ether')); + let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(ETH, ethInWei); + assert.equal(usdInWei.div(10**18).toNumber(), ethInWei.div(10**18).mul(USDETH.div(10**18)).toNumber()); + }); + + it("should get the right conversion for POLY to USD", async() => { + // 40000 POLY to 10000 USD + let polyInWei = BigNumber(web3.utils.toWei('40000', 'ether')); + let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(POLY, polyInWei); + assert.equal(usdInWei.div(10**18).toNumber(), polyInWei.div(10**18).mul(USDPOLY.div(10**18)).toNumber()); + }); + }); + + describe("convertFromUSD", async() => { + + it("should get the right conversion for USD to ETH", async() => { + // 10000 USD to 20 ETH + let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); + let ethInWei = await I_USDTieredSTO_Array[0].convertFromUSD(ETH, usdInWei); + assert.equal(ethInWei.div(10**18).toNumber(), usdInWei.div(10**18).div(USDETH.div(10**18)).toNumber()); + }); + + it("should get the right conversion for USD to POLY", async() => { + // 10000 USD to 40000 POLY + let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); + let polyInWei = await I_USDTieredSTO_Array[0].convertFromUSD(POLY, usdInWei); + assert.equal(polyInWei.div(10**18).toNumber(), usdInWei.div(10**18).div(USDPOLY.div(10**18)).toNumber()); + }); + }); }); - it('should fail and revert when all tiers sold out', async () => { - let stoId = 2; - let tierId = 1; - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, false, 'TOKEN', 'USD', investment_Token); - let investment_ETH = await convert(stoId, tierId, false, 'TOKEN', 'ETH', investment_Token); - let investment_POLY = await convert(stoId, tierId, false, 'TOKEN', 'POLY', investment_Token); - - await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, 'STO is not showing correct status'); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Buy with ETH ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); - }); - - it('should fail and revert when all tiers sold out despite oracle price change', async () => { - let stoId = 2; - let tierId = 1; - - // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - - let investment_Token = BigNumber(5).mul(10 ** 18); - let investment_USD = await convert(stoId, tierId, true, 'TOKEN', 'USD', investment_Token); - - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY - - await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); - await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: ACCREDITED1 }); - - // Change exchange rates up - await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Buy with ETH ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Change exchange rates down - await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); - - // Buy with ETH NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY NONACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Buy with ETH ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) - ); - - // Buy with POLY ACCREDITED - - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }) - ); - - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); - }); - - describe('Test getter functions', async () => { - describe('Generic', async () => { - it('should get the right number of investors', async () => { - assert.equal( - (await I_USDTieredSTO_Array[0].investorCount.call()).toNumber(), - (await I_USDTieredSTO_Array[0].investorCount()).toNumber(), - 'Investor count not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[1].investorCount.call()).toNumber(), - (await I_USDTieredSTO_Array[1].investorCount()).toNumber(), - 'Investor count not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[2].investorCount.call()).toNumber(), - (await I_USDTieredSTO_Array[2].investorCount()).toNumber(), - 'Investor count not changed as expected' - ); - }); - - it('should get the right amounts invested', async () => { - assert.equal( - (await I_USDTieredSTO_Array[0].fundsRaised.call(ETH)).toNumber(), - (await I_USDTieredSTO_Array[0].getRaised(0)).toNumber(), - 'getRaisedEther not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[0].fundsRaised.call(POLY)).toNumber(), - (await I_USDTieredSTO_Array[0].getRaised(1)).toNumber(), - 'getRaisedPOLY not changed as expected' - ); - assert.equal( - (await I_USDTieredSTO_Array[0].fundsRaisedUSD.call()).toNumber(), - (await I_USDTieredSTO_Array[0].fundsRaisedUSD()).toNumber(), - 'fundsRaisedUSD not changed as expected' - ); - }); - }); - - describe('convertToUSD', async () => { - it('should reset exchange rates', async () => { - // Reset exchange rates - await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); - await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); - }); - - it('should get the right conversion for ETH to USD', async () => { - // 20 ETH to 10000 USD - let ethInWei = BigNumber(web3.utils.toWei('20', 'ether')); - let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(ETH, ethInWei); - assert.equal( - usdInWei.div(10 ** 18).toNumber(), - ethInWei - .div(10 ** 18) - .mul(USDETH.div(10 ** 18)) - .toNumber() - ); - }); - - it('should get the right conversion for POLY to USD', async () => { - // 40000 POLY to 10000 USD - let polyInWei = BigNumber(web3.utils.toWei('40000', 'ether')); - let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(POLY, polyInWei); - assert.equal( - usdInWei.div(10 ** 18).toNumber(), - polyInWei - .div(10 ** 18) - .mul(USDPOLY.div(10 ** 18)) - .toNumber() - ); - }); - }); - - describe('convertFromUSD', async () => { - it('should get the right conversion for USD to ETH', async () => { - // 10000 USD to 20 ETH - let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); - let ethInWei = await I_USDTieredSTO_Array[0].convertFromUSD(ETH, usdInWei); - assert.equal( - ethInWei.div(10 ** 18).toNumber(), - usdInWei - .div(10 ** 18) - .div(USDETH.div(10 ** 18)) - .toNumber() - ); - }); - - it('should get the right conversion for USD to POLY', async () => { - // 10000 USD to 40000 POLY - let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); - let polyInWei = await I_USDTieredSTO_Array[0].convertFromUSD(POLY, usdInWei); - assert.equal( - polyInWei.div(10 ** 18).toNumber(), - usdInWei - .div(10 ** 18) - .div(USDPOLY.div(10 ** 18)) - .toNumber() - ); - }); - }); - }); - - describe('Test cases for the USDTieredSTOFactory', async () => { - it('should get the exact details of the factory', async () => { - assert.equal((await I_USDTieredSTOFactory.setupCost.call()).toNumber(), STOSetupCost); - assert.equal(await I_USDTieredSTOFactory.getType.call(), 3); - assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), 'USDTieredSTO', 'Wrong Module added'); - assert.equal(await I_USDTieredSTOFactory.getDescription.call(), 'USD Tiered STO', 'Wrong Module added'); - assert.equal(await I_USDTieredSTOFactory.getTitle.call(), 'USD Tiered STO', 'Wrong Module added'); - assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), 'Initialises a USD tiered STO.', 'Wrong Module added'); - let tags = await I_USDTieredSTOFactory.getTags.call(); - assert.equal(web3.utils.hexToString(tags[0]), 'USD'); - assert.equal(web3.utils.hexToString(tags[1]), 'Tiered'); - assert.equal(web3.utils.hexToString(tags[2]), 'POLY'); - assert.equal(web3.utils.hexToString(tags[3]), 'ETH'); - }); - }); + describe("Test cases for the USDTieredSTOFactory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal((await I_USDTieredSTOFactory.setupCost.call()).toNumber(), STOSetupCost); + assert.equal(await I_USDTieredSTOFactory.getType.call(),3); + assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), + "USDTieredSTO", + "Wrong Module added"); + assert.equal(await I_USDTieredSTOFactory.getDescription.call(), + "USD Tiered STO", + "Wrong Module added"); + assert.equal(await I_USDTieredSTOFactory.getTitle.call(), + "USD Tiered STO", + "Wrong Module added"); + assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), + "Initialises a USD tiered STO.", + "Wrong Module added"); + let tags = await I_USDTieredSTOFactory.getTags.call(); + assert.equal(web3.utils.hexToString(tags[0]),"USD"); + assert.equal(web3.utils.hexToString(tags[1]),"Tiered"); + assert.equal(web3.utils.hexToString(tags[2]),"POLY"); + assert.equal(web3.utils.hexToString(tags[3]),"ETH"); + + }); + }); }); diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index 70d60284f..b41da159e 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -4,7 +4,7 @@ import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); const USDTieredSTO = artifacts.require('./USDTieredSTO.sol'); const MockOracle = artifacts.require('./MockOracle.sol'); @@ -24,86 +24,86 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port const TOLERANCE = 2; // Allow balances to be off by 2 WEI for rounding purposes contract('USDTieredSTO Sim', accounts => { - // Accounts Variable declaration - let POLYMATH; - let ISSUER; - let WALLET; - let RESERVEWALLET; - let INVESTOR1; - let ACCREDITED1; - let ACCREDITED2; - let NONACCREDITED1; - let NONACCREDITED2; - let NOTWHITELISTED; - let NOTAPPROVED; - - let MESSAGE = 'Transaction Should Fail!'; - const GAS_PRICE = 10000000000; // 10 GWEI - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralTransferManagerFactory; - let I_USDTieredSTOProxyFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_USDTieredSTOFactory; - let I_USDOracle; - let I_POLYOracle; - let I_STFactory; - let I_MRProxied; - let I_STRProxied; - let I_SecurityToken; - let I_USDTieredSTO_Array = []; - let I_PolyToken; - let I_DaiToken; - let I_PolymathRegistry; - - // SecurityToken Details for funds raise Type ETH - const NAME = 'Team'; - const SYMBOL = 'SAP'; - const TOKENDETAILS = 'This is equity type of issuance'; - const DECIMALS = 18; - - // Module key - const TMKEY = 2; - const STOKEY = 3; - - // Initial fee for ticker registry and security token registry - const REGFEE = web3.utils.toWei('250'); - const STOSetupCost = 0; - - // MockOracle USD prices - const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH - const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - // STO Configuration Arrays - let _startTime = []; - let _endTime = []; - let _ratePerTier = []; - let _ratePerTierDiscountPoly = []; - let _tokensPerTierTotal = []; - let _tokensPerTierDiscountPoly = []; - let _nonAccreditedLimitUSD = []; - let _minimumInvestmentUSD = []; - let _fundRaiseTypes = []; - let _wallet = []; - let _reserveWallet = []; - let _usdToken = []; - - /* function configure( + // Accounts Variable declaration + let POLYMATH; + let ISSUER; + let WALLET; + let RESERVEWALLET; + let INVESTOR1; + let ACCREDITED1; + let ACCREDITED2; + let NONACCREDITED1; + let NONACCREDITED2; + let NOTWHITELISTED; + let NOTAPPROVED; + + let MESSAGE = "Transaction Should Fail!"; + const GAS_PRICE = 10000000000; // 10 GWEI + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_USDTieredSTOProxyFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_USDTieredSTOFactory; + let I_USDOracle; + let I_POLYOracle; + let I_STFactory; + let I_MRProxied; + let I_STRProxied; + let I_SecurityToken; + let I_USDTieredSTO_Array = []; + let I_PolyToken; + let I_DaiToken; + let I_PolymathRegistry; + + // SecurityToken Details for funds raise Type ETH + const NAME = "Team"; + const SYMBOL = "SAP"; + const TOKENDETAILS = "This is equity type of issuance"; + const DECIMALS = 18; + + // Module key + const TMKEY = 2; + const STOKEY = 3; + + // Initial fee for ticker registry and security token registry + const REGFEE = web3.utils.toWei("250"); + const STOSetupCost = 0; + + // MockOracle USD prices + const USDETH = BigNumber(500).mul(10**18); // 500 USD/ETH + const USDPOLY = BigNumber(25).mul(10**16); // 0.25 USD/POLY + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + // STO Configuration Arrays + let _startTime = []; + let _endTime = []; + let _ratePerTier = []; + let _ratePerTierDiscountPoly = []; + let _tokensPerTierTotal = []; + let _tokensPerTierDiscountPoly = []; + let _nonAccreditedLimitUSD = []; + let _minimumInvestmentUSD = []; + let _fundRaiseTypes = []; + let _wallet = []; + let _reserveWallet = []; + let _usdToken = []; + + /* function configure( uint256 _startTime, uint256 _endTime, uint256[] _ratePerTier, @@ -117,197 +117,184 @@ contract('USDTieredSTO Sim', accounts => { address _reserveWallet, address _usdToken ) */ - const functionSignature = { - name: 'configure', - type: 'function', - inputs: [ - { - type: 'uint256', - name: '_startTime' - }, - { - type: 'uint256', - name: '_endTime' - }, - { - type: 'uint256[]', - name: '_ratePerTier' - }, - { - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - }, - { - type: 'uint256[]', - name: '_tokensPerTier' - }, - { - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - }, - { - type: 'uint256', - name: '_nonAccreditedLimitUSD' - }, - { - type: 'uint256', - name: '_minimumInvestmentUSD' - }, - { - type: 'uint8[]', - name: '_fundRaiseTypes' - }, - { - type: 'address', - name: '_wallet' - }, - { - type: 'address', - name: '_reserveWallet' - }, - { - type: 'address', - name: '_usdToken' - } - ] - }; - - function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - } - - before(async () => { - // Accounts setup - POLYMATH = accounts[0]; - ISSUER = accounts[1]; - WALLET = accounts[2]; - RESERVEWALLET = WALLET; - ACCREDITED1 = accounts[3]; - ACCREDITED2 = accounts[4]; - NONACCREDITED1 = accounts[5]; - NONACCREDITED2 = accounts[6]; - NOTWHITELISTED = accounts[7]; - NOTAPPROVED = accounts[8]; - INVESTOR1 = accounts[9]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: POLYMATH - }); + const functionSignature = { + name: 'configure', + type: 'function', + inputs: [{ + type: 'uint256', + name: '_startTime' + },{ + type: 'uint256', + name: '_endTime' + },{ + type: 'uint256[]', + name: '_ratePerTier' + },{ + type: 'uint256[]', + name: '_ratePerTierDiscountPoly' + },{ + type: 'uint256[]', + name: '_tokensPerTier' + },{ + type: 'uint256[]', + name: '_tokensPerTierDiscountPoly' + },{ + type: 'uint256', + name: '_nonAccreditedLimitUSD' + },{ + type: 'uint256', + name: '_minimumInvestmentUSD' + },{ + type: 'uint8[]', + name: '_fundRaiseTypes' + },{ + type: 'address', + name: '_wallet' + },{ + type: 'address', + name: '_reserveWallet' + },{ + type: 'address', + name: '_usdToken' + }] + }; + + function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + before(async() => { + // Accounts setup + POLYMATH = accounts[0]; + ISSUER = accounts[1]; + WALLET = accounts[2]; + RESERVEWALLET = WALLET; + ACCREDITED1 = accounts[3]; + ACCREDITED2 = accounts[4]; + NONACCREDITED1 = accounts[5]; + NONACCREDITED2 = accounts[6]; + NOTWHITELISTED = accounts[7]; + NOTAPPROVED = accounts[8]; + INVESTOR1 = accounts[9]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + I_DaiToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), ISSUER); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: POLYMATH + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + + // STEP 3: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - // STEP 3: Deploy the ModuleRegistry + // STEP 4: Deploy the GeneralDelegateManagerFactory - I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - // STEP 3: Deploy the GeneralTransferManagerFactory + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + // STEP 5: Deploy the proxy + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + // STEP 6: Deploy the USDTieredSTOFactory - // STEP 4: Deploy the GeneralDelegateManagerFactory + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: ISSUER }); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "USDTieredSTOFactory contract was not deployed" + ); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - // STEP 5: Deploy the proxy - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - // STEP 6: Deploy the USDTieredSTOFactory + // Step 8: Deploy the STFactory contract - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { - from: ISSUER - }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 9: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 10: update the registries addresses from the PolymathRegistry contract + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: POLYMATH}); + await I_MRProxied.updateFromRegistry({from: POLYMATH}); + + // STEP 7: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'USDTieredSTOFactory contract was not deployed' - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - REGFEE, - REGFEE, - I_PolyToken.address, - POLYMATH - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); - await I_MRProxied.updateFromRegistry({ from: POLYMATH }); - - // STEP 7: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); - - // 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 }); - await I_PolymathRegistry.changeAddress('PolyUsdOracle', I_POLYOracle.address, { from: POLYMATH }); - - // Printing all the contract addresses - console.log(` + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + + // 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 }); + await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -326,147 +313,125 @@ contract('USDTieredSTO Sim', accounts => { USDTieredSTOProxyFactory: ${I_USDTieredSTOProxyFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Deploy the STO', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from: ISSUER }); - assert.equal(tx.logs[0].args._owner, ISSUER); - assert.equal(tx.logs[0].args._ticker, SYMBOL); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.getTokens(REGFEE, ISSUER); - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); - assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), TMKEY); - assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(TMKEY, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - it('Should successfully attach the first STO module to the security token', async () => { - let stoId = 0; - - _startTime.push(latestTime() + duration.days(2)); - _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(0.05 * 10 ** 18), BigNumber(0.13 * 10 ** 18), BigNumber(0.17 * 10 ** 18)]); // [ 0.05 USD/Token, 0.10 USD/Token, 0.15 USD/Token ] - _ratePerTierDiscountPoly.push([BigNumber(0.05 * 10 ** 18), BigNumber(0.08 * 10 ** 18), BigNumber(0.13 * 10 ** 18)]); // [ 0.05 USD/Token, 0.08 USD/Token, 0.13 USD/Token ] - _tokensPerTierTotal.push([BigNumber(200 * 10 ** 18), BigNumber(500 * 10 ** 18), BigNumber(300 * 10 ** 18)]); // [ 1000 Token, 2000 Token, 1500 Token ] - _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(50 * 10 ** 18), BigNumber(300 * 10 ** 18)]); // [ 0 Token, 1000 Token, 1500 Token ] - _nonAccreditedLimitUSD.push(BigNumber(10 * 10 ** 18)); // 20 USD - _minimumInvestmentUSD.push(BigNumber(0)); // 1 wei USD - _fundRaiseTypes.push([0, 1, 2]); - _wallet.push(WALLET); - _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address); - - let config = [ - _startTime[stoId], - _endTime[stoId], - _ratePerTier[stoId], - _ratePerTierDiscountPoly[stoId], - _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], - _nonAccreditedLimitUSD[stoId], - _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], - _wallet[stoId], - _reserveWallet[stoId], - _usdToken[stoId] - ]; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(' Gas addModule: '.grey + tx.receipt.gasUsed.toString().grey); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); - I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - - assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], 'Incorrect _startTime in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], 'Incorrect _endTime in config'); - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), - _ratePerTier[stoId][i].toNumber(), - 'Incorrect _ratePerTier in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), - _ratePerTierDiscountPoly[stoId][i].toNumber(), - 'Incorrect _ratePerTierDiscountPoly in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), - _tokensPerTierTotal[stoId][i].toNumber(), - 'Incorrect _tokensPerTierTotal in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), - _tokensPerTierDiscountPoly[stoId][i].toNumber(), - 'Incorrect _tokensPerTierDiscountPoly in config' - ); - } - assert.equal( - (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), - _nonAccreditedLimitUSD[stoId].toNumber(), - 'Incorrect _nonAccreditedLimitUSD in config' - ); - assert.equal( - (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), - _minimumInvestmentUSD[stoId].toNumber(), - 'Incorrect _minimumInvestmentUSD in config' - ); - assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], 'Incorrect _wallet in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(), _reserveWallet[stoId], 'Incorrect _reserveWallet in config'); - assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, 'Incorrect number of tiers'); - assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, 'Incorrect number of permissions'); + describe("Deploy the STO", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from : ISSUER }); + assert.equal(tx.logs[0].args._owner, ISSUER); + assert.equal(tx.logs[0].args._ticker, SYMBOL); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.getTokens(REGFEE, ISSUER); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, { from: ISSUER }); + assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), TMKEY); + assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(TMKEY, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + it("Should successfully attach the first STO module to the security token", async () => { + let stoId = 0; + + _startTime.push(latestTime() + duration.days(2)); + _endTime.push(_startTime[stoId] + duration.days(100)); + _ratePerTier.push([ + BigNumber(0.05*10**18), BigNumber(0.13*10**18), BigNumber(0.17*10**18) + ]); // [ 0.05 USD/Token, 0.10 USD/Token, 0.15 USD/Token ] + _ratePerTierDiscountPoly.push([ + BigNumber(0.05*10**18), BigNumber(0.08*10**18), BigNumber(0.13*10**18) + ]); // [ 0.05 USD/Token, 0.08 USD/Token, 0.13 USD/Token ] + _tokensPerTierTotal.push([ + BigNumber(200*10**18), BigNumber(500*10**18), BigNumber(300*10**18) + ]); // [ 1000 Token, 2000 Token, 1500 Token ] + _tokensPerTierDiscountPoly.push([ + BigNumber(0), BigNumber(50*10**18), BigNumber(300*10**18) + ]); // [ 0 Token, 1000 Token, 1500 Token ] + _nonAccreditedLimitUSD.push(BigNumber(10*10**18)); // 20 USD + _minimumInvestmentUSD.push(BigNumber(0)); // 1 wei USD + _fundRaiseTypes.push([0,1,2]); + _wallet.push(WALLET); + _reserveWallet.push(RESERVEWALLET); + _usdToken.push(I_DaiToken.address); + + let config = [ + _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); + + assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); + } + assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); + assert.equal((await I_USDTieredSTO_Array[stoId].getNumberOfTiers()), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); + assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); + }); + + it("Should successfully prepare the STO", async() => { + let stoId = 0; + + // Start STO + await increaseTime(duration.days(3)); + + // Whitelist + let fromTime = latestTime() + duration.days(15); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let canBuyFromSTO = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NOTAPPROVED, fromTime, toTime, expiryTime, false, { from: ISSUER }); + + await increaseTime(duration.days(3)); + + // Accreditation + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1, ACCREDITED2], [true, true], { from: ISSUER }); + await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, NONACCREDITED2], [false, false], { from: ISSUER }); + }); }); - it('Should successfully prepare the STO', async () => { - let stoId = 0; - - // Start STO - await increaseTime(duration.days(3)); - - // Whitelist - let fromTime = latestTime() + duration.days(15); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let canBuyFromSTO = true; - - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED2, fromTime, toTime, expiryTime, canBuyFromSTO, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NOTAPPROVED, fromTime, toTime, expiryTime, false, { from: ISSUER }); - - await increaseTime(duration.days(3)); - - // Accreditation - await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1, ACCREDITED2], [true, true], { from: ISSUER }); - await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, NONACCREDITED2], [false, false], { from: ISSUER }); - }); - }); + describe("Simulate purchasing", async() => { - describe('Simulate purchasing', async () => { - it('Should successfully complete simulation', async () => { - let stoId = 0; + it("Should successfully complete simulation", async() => { + let stoId = 0; - console.log(` + console.log(` ------------------- Investor Addresses ------------------- ACCREDITED1: ${ACCREDITED1} ACCREDITED2: ${ACCREDITED2} @@ -477,505 +442,320 @@ contract('USDTieredSTO Sim', accounts => { ---------------------------------------------------------- `); - let totalTokens = BigNumber(0); - for (var i = 0; i < _tokensPerTierTotal[stoId].length; i++) { - totalTokens = totalTokens.add(_tokensPerTierTotal[stoId][i]); - } - console.log('totalTokens: ' + totalTokens.div(10 ** 18).toNumber()); - let tokensSold = BigNumber(0); - while (true) { - switch (getRandomInt(0, 5)) { - case 0: // ACCREDITED1 - await invest(ACCREDITED1, true); - break; - case 1: // ACCREDITED2 - await invest(ACCREDITED2, true); - break; - case 2: // NONACCREDITED1 - let usd_NONACCREDITED1 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); - if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED1)) - // under non-accredited cap - await invest(NONACCREDITED1, false); - // over non-accredited cap - else await investFAIL(NONACCREDITED1); - break; - case 3: // NONACCREDITED2 - let usd_NONACCREDITED2 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED2); - if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED2)) - // under non-accredited cap - await invest(NONACCREDITED2, false); - // over non-accredited cap - else await investFAIL(NONACCREDITED2); - break; - case 4: // NOTWHITELISTED - await investFAIL(NOTWHITELISTED); - break; - case 5: // NOTAPPROVED - await investFAIL(NOTAPPROVED); - break; - } - console.log('Next round'); - tokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - console.log('Tokens Sold: ' + tokensSold.toString()); - if (tokensSold.gte(totalTokens.sub(1 * 10 ** 18))) { - console.log(`${tokensSold} tokens sold, simulation completed successfully!`.green); - break; - } - } - - async function invest(_investor, _isAccredited) { - // need to add check if reached non-accredited cap - let USD_remaining; - if (!_isAccredited) { - let USD_to_date = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(_investor); - USD_remaining = _nonAccreditedLimitUSD[stoId].sub(USD_to_date); - } else { - USD_remaining = totalTokens.mul(2); - } - - let log_remaining = USD_remaining; - let isPoly = Math.random() >= 0.33; - let isDai = Math.random() >= 0.33; - - let Token_counter = BigNumber(getRandomInt(1 * 10 ** 10, 50 * 10 ** 10)).mul(10 ** 8); - let investment_USD = BigNumber(0); - let investment_ETH = BigNumber(0); - let investment_POLY = BigNumber(0); - let investment_DAI = BigNumber(0); - let investment_Token = BigNumber(0); - - let Tokens_total = []; - let Tokens_discount = []; - for (var i = 0; i < _ratePerTier[stoId].length; i++) { - Tokens_total.push( - (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(i)) - ); - Tokens_discount.push( - (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).sub( - await I_USDTieredSTO_Array[stoId].mintedPerTierDiscountPoly.call(i) - ) - ); - } - - let tier = 0; - let Token_Tier; - let USD_Tier; - let POLY_Tier; - let ETH_Tier; - let DAI_Tier; - - let USD_overflow; - let Token_overflow; - - while (Token_counter.gt(0)) { - if (tier == _ratePerTier[stoId].length) { - break; - } - if (Tokens_total[tier].gt(0)) { - if (isPoly) { - // 1. POLY and discount (consume up to cap then move to regular) - if (Tokens_discount[tier].gt(0)) { - Token_Tier = BigNumber.min([Tokens_total[tier], Tokens_discount[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTierDiscountPoly[stoId][tier].div(10 ** 18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTierDiscountPoly[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); + let totalTokens = BigNumber(0); + for (var i = 0; i < _tokensPerTierTotal[stoId].length; i++) { + totalTokens = totalTokens.add(_tokensPerTierTotal[stoId][i]); + } + console.log('totalTokens: '+totalTokens.div(10**18).toNumber()); + let tokensSold = BigNumber(0); + while (true) { + switch (getRandomInt(0,5)) { + case 0: // ACCREDITED1 + await invest(ACCREDITED1, true); + break; + case 1: // ACCREDITED2 + await invest(ACCREDITED2, true); + break; + case 2: // NONACCREDITED1 + let usd_NONACCREDITED1 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); + if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED1)) // under non-accredited cap + await invest(NONACCREDITED1, false); + else // over non-accredited cap + await investFAIL(NONACCREDITED1); + break; + case 3: // NONACCREDITED2 + let usd_NONACCREDITED2 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED2); + if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED2)) // under non-accredited cap + await invest(NONACCREDITED2, false); + else // over non-accredited cap + await investFAIL(NONACCREDITED2); + break; + case 4: // NOTWHITELISTED + await investFAIL(NOTWHITELISTED); + break; + case 5: // NOTAPPROVED + await investFAIL(NOTAPPROVED); + break; } - POLY_Tier = USD_Tier.mul(10 ** 18) - .round(0) - .div(USDPOLY) - .round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Tokens_discount[tier] = Tokens_discount[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_POLY = investment_POLY.add(POLY_Tier); - } - // 2. POLY and regular (consume up to cap then skip to next tier) - if (Tokens_total[tier].gt(0) && Token_counter.gt(0)) { - Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); + console.log("Next round"); + tokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + console.log("Tokens Sold: " + tokensSold.toString()); + if (tokensSold.gte(totalTokens.sub(1*10**18))) { + console.log(`${tokensSold} tokens sold, simulation completed successfully!`.green); + break; } - POLY_Tier = USD_Tier.mul(10 ** 18) - .round(0) - .div(USDPOLY) - .round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_POLY = investment_POLY.add(POLY_Tier); - } - } else if (isDai) { - // 3. DAI (consume up to cap then skip to next tier) - Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); - } - DAI_Tier = USD_Tier.round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_DAI = investment_USD; - } else { - // 4. ETH (consume up to cap then skip to next tier) - Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); - if (USD_Tier.gte(USD_remaining)) { - USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); - USD_Tier = USD_Tier.sub(USD_overflow); - Token_Tier = Token_Tier.sub(Token_overflow); - Token_counter = BigNumber(0); - } - ETH_Tier = USD_Tier.mul(10 ** 18) - .round(0) - .div(USDETH) - .round(0); - USD_remaining = USD_remaining.sub(USD_Tier); - Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); - Token_counter = Token_counter.sub(Token_Tier); - investment_Token = investment_Token.add(Token_Tier); - investment_USD = investment_USD.add(USD_Tier); - investment_ETH = investment_ETH.add(ETH_Tier); } - } - tier++; - } - - await processInvestment( - _investor, - investment_Token, - investment_USD, - investment_POLY, - investment_DAI, - investment_ETH, - isPoly, - isDai, - log_remaining, - Tokens_total, - Tokens_discount, - tokensSold - ); - } - - async function investFAIL(_investor) { - let isPoly = Math.random() >= 0.3; - let isDAI = Math.random() >= 0.3; - let investment_POLY = BigNumber(40 * 10 ** 18); // 10 USD = 40 POLY - let investment_ETH = BigNumber(0.02 * 10 ** 18); // 10 USD = 0.02 ETH - let investment_DAI = BigNumber(10 * 10 ** 18); // 10 USD = DAI DAI - - await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); - } - - async function processInvestment( - _investor, - investment_Token, - investment_USD, - investment_POLY, - investment_DAI, - investment_ETH, - isPoly, - isDai, - log_remaining, - Tokens_total, - Tokens_discount, - tokensSold - ) { - investment_Token = investment_Token.round(0); - investment_USD = investment_USD.round(0); - investment_POLY = investment_POLY.round(0); - investment_DAI = investment_DAI.round(0); - investment_ETH = investment_ETH.round(0); - console.log(` + + async function invest(_investor, _isAccredited) { // need to add check if reached non-accredited cap + let USD_remaining; + if (!_isAccredited) { + let USD_to_date = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(_investor); + USD_remaining = _nonAccreditedLimitUSD[stoId].sub(USD_to_date); + } else { + USD_remaining = totalTokens.mul(2); + } + + let log_remaining = USD_remaining; + let isPoly = Math.random() >= 0.33; + let isDai = Math.random() >= 0.33; + + let Token_counter = BigNumber(getRandomInt(1*10**10,50*10**10)).mul(10**8); + let investment_USD = BigNumber(0); + let investment_ETH = BigNumber(0); + let investment_POLY = BigNumber(0); + let investment_DAI = BigNumber(0); + let investment_Token = BigNumber(0); + + let Tokens_total = []; + let Tokens_discount = []; + for (var i = 0; i < _ratePerTier[stoId].length; i++) { + Tokens_total.push((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(i))); + Tokens_discount.push((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierDiscountPoly.call(i))); + } + + let tier = 0; + let Token_Tier; + let USD_Tier; + let POLY_Tier; + let ETH_Tier; + let DAI_Tier; + + + let USD_overflow; + let Token_overflow; + + while (Token_counter.gt(0)) { + if (tier == _ratePerTier[stoId].length) { + break; + } + if (Tokens_total[tier].gt(0)) { + if (isPoly) { + // 1. POLY and discount (consume up to cap then move to regular) + if (Tokens_discount[tier].gt(0)) { + Token_Tier = BigNumber.min([Tokens_total[tier], Tokens_discount[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTierDiscountPoly[stoId][tier].div(10**18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10**18).div(_ratePerTierDiscountPoly[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); + } + POLY_Tier = USD_Tier.mul(10**18).round(0).div(USDPOLY).round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Tokens_discount[tier] = Tokens_discount[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_POLY = investment_POLY.add(POLY_Tier); + } + // 2. POLY and regular (consume up to cap then skip to next tier) + if (Tokens_total[tier].gt(0) && Token_counter.gt(0)) { + Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); + } + POLY_Tier = USD_Tier.mul(10**18).round(0).div(USDPOLY).round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_POLY = investment_POLY.add(POLY_Tier); + } + } else if (isDai) { + // 3. DAI (consume up to cap then skip to next tier) + Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); + } + DAI_Tier = USD_Tier.round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_DAI = investment_USD; + } else { + // 4. ETH (consume up to cap then skip to next tier) + Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); + if (USD_Tier.gte(USD_remaining)) { + USD_overflow = USD_Tier.sub(USD_remaining); + Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); + USD_Tier = USD_Tier.sub(USD_overflow); + Token_Tier = Token_Tier.sub(Token_overflow); + Token_counter = BigNumber(0); + } + ETH_Tier = USD_Tier.mul(10**18).round(0).div(USDETH).round(0); + USD_remaining = USD_remaining.sub(USD_Tier); + Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); + Token_counter = Token_counter.sub(Token_Tier); + investment_Token = investment_Token.add(Token_Tier); + investment_USD = investment_USD.add(USD_Tier); + investment_ETH = investment_ETH.add(ETH_Tier); + } + } + tier++ + } + + await processInvestment(_investor, investment_Token, investment_USD, investment_POLY, investment_DAI, investment_ETH, isPoly, isDai, log_remaining, Tokens_total, Tokens_discount, tokensSold); + } + + async function investFAIL(_investor) { + let isPoly = Math.random() >= 0.3; + let isDAI = Math.random() >= 0.3; + let investment_POLY = BigNumber(40*10**18); // 10 USD = 40 POLY + let investment_ETH = BigNumber(0.02*10**18); // 10 USD = 0.02 ETH + let investment_DAI = BigNumber(10*10**18); // 10 USD = DAI DAI + + + await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); + } + + async function processInvestment(_investor, investment_Token, investment_USD, investment_POLY, investment_DAI, investment_ETH, isPoly, isDai, log_remaining, Tokens_total, Tokens_discount, tokensSold) { + investment_Token = investment_Token.round(0); + investment_USD = investment_USD.round(0); + investment_POLY = investment_POLY.round(0); + investment_DAI = investment_DAI.round(0); + investment_ETH = investment_ETH.round(0); + console.log(` ------------------- New Investment ------------------- Investor: ${_investor} - N-A USD Remaining: ${log_remaining.div(10 ** 18)} + N-A USD Remaining: ${log_remaining.div(10**18)} Total Cap Remaining: ${Tokens_total} Discount Cap Remaining: ${Tokens_discount} - Total Tokens Sold: ${tokensSold.div(10 ** 18)} - Token Investment: ${investment_Token.div(10 ** 18)} - USD Investment: ${investment_USD.div(10 ** 18)} - POLY Investment: ${investment_POLY.div(10 ** 18)} - DAI Investment: ${investment_DAI.div(10 ** 18)} - ETH Investment: ${investment_ETH.div(10 ** 18)} + Total Tokens Sold: ${tokensSold.div(10**18)} + Token Investment: ${investment_Token.div(10**18)} + USD Investment: ${investment_USD.div(10**18)} + POLY Investment: ${investment_POLY.div(10**18)} + DAI Investment: ${investment_DAI.div(10**18)} + ETH Investment: ${investment_ETH.div(10**18)} ------------------------------------------------------ `); - if (isPoly) { - await I_PolyToken.getTokens(investment_POLY, _investor); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: _investor }); - } else if (isDai) { - await I_DaiToken.getTokens(investment_DAI, _investor); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: _investor }); - } - - // console.log(await I_USDTieredSTO_Array[stoId].isOpen()); - - let init_TokenSupply = await I_SecurityToken.totalSupply(); - let init_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); - let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); - let init_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); - let init_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); - let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); - let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); - let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); - let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - let tx; - let gasCost = BigNumber(0); - - if (isPoly && investment_POLY.gt(10)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE }); - gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log( - `buyWithPOLY: ${investment_Token.div(10 ** 18)} tokens for ${investment_POLY.div(10 ** 18)} POLY by ${_investor}`.yellow - ); - } else if (isDai && investment_DAI.gt(10)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE }); - gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log( - `buyWithUSD: ${investment_Token.div(10 ** 18)} tokens for ${investment_DAI.div(10 ** 18)} DAI by ${_investor}`.yellow - ); - } else if (investment_ETH.gt(0)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE }); - gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log( - `buyWithETH: ${investment_Token.div(10 ** 18)} tokens for ${investment_ETH.div(10 ** 18)} ETH by ${_investor}`.yellow - ); - } - console.log(investment_POLY.toNumber()); - - let final_TokenSupply = await I_SecurityToken.totalSupply(); - let final_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); - let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); - let final_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); - let final_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); - let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); - let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); - let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); - let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); - let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); - let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); - let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); - let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - - // console.log('init_TokenSupply: '+init_TokenSupply.div(10**18).toNumber()); - // console.log('final_TokenSupply: '+final_TokenSupply.div(10**18).toNumber()); - - if (isPoly) { - assert.closeTo( - final_TokenSupply.toNumber(), - init_TokenSupply.add(investment_Token).toNumber(), - TOLERANCE, - 'Token Supply not changed as expected' - ); - assert.closeTo( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - TOLERANCE, - 'Investor Token Balance not changed as expected' - ); - assert.closeTo( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost).toNumber(), - TOLERANCE, - 'Investor ETH Balance not changed as expected' - ); - assert.closeTo( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.sub(investment_POLY).toNumber(), - TOLERANCE, - 'Investor POLY Balance not changed as expected' - ); - assert.closeTo( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - TOLERANCE, - 'STO Token Sold not changed as expected' - ); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, 'STO ETH Balance not changed as expected'); - assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, 'STO POLY Balance not changed as expected'); - assert.closeTo( - final_RaisedUSD.toNumber(), - init_RaisedUSD.add(investment_USD).toNumber(), - TOLERANCE, - 'Raised USD not changed as expected' - ); - assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, 'Raised ETH not changed as expected'); - assert.closeTo( - final_RaisedPOLY.toNumber(), - init_RaisedPOLY.add(investment_POLY).toNumber(), - TOLERANCE, - 'Raised POLY not changed as expected' - ); - assert.closeTo( - final_WalletETHBal.toNumber(), - init_WalletETHBal.toNumber(), - TOLERANCE, - 'Wallet ETH Balance not changed as expected' - ); - assert.closeTo( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.add(investment_POLY).toNumber(), - TOLERANCE, - 'Wallet POLY Balance not changed as expected' - ); - } else if (isDai) { - assert.closeTo( - final_TokenSupply.toNumber(), - init_TokenSupply.add(investment_Token).toNumber(), - TOLERANCE, - 'Token Supply not changed as expected' - ); - assert.closeTo( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - TOLERANCE, - 'Investor Token Balance not changed as expected' - ); - assert.closeTo( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal.sub(gasCost).toNumber(), - TOLERANCE, - 'Investor ETH Balance not changed as expected' - ); - assert.closeTo( - final_InvestorDAIBal.toNumber(), - init_InvestorDAIBal.sub(investment_DAI).toNumber(), - TOLERANCE, - 'Investor DAI Balance not changed as expected' - ); - assert.closeTo( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - TOLERANCE, - 'STO Token Sold not changed as expected' - ); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, 'STO ETH Balance not changed as expected'); - assert.closeTo(final_STODAIBal.toNumber(), init_STODAIBal.toNumber(), TOLERANCE, 'STO DAI Balance not changed as expected'); - assert.closeTo( - final_RaisedUSD.toNumber(), - init_RaisedUSD.add(investment_USD).toNumber(), - TOLERANCE, - 'Raised USD not changed as expected' - ); - assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, 'Raised ETH not changed as expected'); - assert.closeTo( - final_RaisedDAI.toNumber(), - init_RaisedDAI.add(investment_DAI).toNumber(), - TOLERANCE, - 'Raised DAI not changed as expected' - ); - assert.closeTo( - final_WalletETHBal.toNumber(), - init_WalletETHBal.toNumber(), - TOLERANCE, - 'Wallet ETH Balance not changed as expected' - ); - assert.closeTo( - final_WalletDAIBal.toNumber(), - init_WalletDAIBal.add(investment_DAI).toNumber(), - TOLERANCE, - 'Wallet DAI Balance not changed as expected' - ); - } else { - assert.closeTo( - final_TokenSupply.toNumber(), - init_TokenSupply.add(investment_Token).toNumber(), - TOLERANCE, - 'Token Supply not changed as expected' - ); - assert.closeTo( - final_InvestorTokenBal.toNumber(), - init_InvestorTokenBal.add(investment_Token).toNumber(), - TOLERANCE, - 'Investor Token Balance not changed as expected' - ); - assert.closeTo( - final_InvestorETHBal.toNumber(), - init_InvestorETHBal - .sub(gasCost) - .sub(investment_ETH) - .toNumber(), - TOLERANCE, - 'Investor ETH Balance not changed as expected' - ); - assert.closeTo( - final_InvestorPOLYBal.toNumber(), - init_InvestorPOLYBal.toNumber(), - TOLERANCE, - 'Investor POLY Balance not changed as expected' - ); - assert.closeTo( - final_STOTokenSold.toNumber(), - init_STOTokenSold.add(investment_Token).toNumber(), - TOLERANCE, - 'STO Token Sold not changed as expected' - ); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, 'STO ETH Balance not changed as expected'); - assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, 'STO POLY Balance not changed as expected'); - assert.closeTo( - final_RaisedUSD.toNumber(), - init_RaisedUSD.add(investment_USD).toNumber(), - TOLERANCE, - 'Raised USD not changed as expected' - ); - assert.closeTo( - final_RaisedETH.toNumber(), - init_RaisedETH.add(investment_ETH).toNumber(), - TOLERANCE, - 'Raised ETH not changed as expected' - ); - assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), TOLERANCE, 'Raised POLY not changed as expected'); - assert.closeTo( - final_WalletETHBal.toNumber(), - init_WalletETHBal.add(investment_ETH).toNumber(), - TOLERANCE, - 'Wallet ETH Balance not changed as expected' - ); - assert.closeTo( - final_WalletPOLYBal.toNumber(), - init_WalletPOLYBal.toNumber(), - TOLERANCE, - 'Wallet POLY Balance not changed as expected' - ); - } - } + if (isPoly) { + await I_PolyToken.getTokens(investment_POLY, _investor); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: _investor}); + } else if (isDai) { + await I_DaiToken.getTokens(investment_DAI, _investor); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: _investor}); + } + + // console.log(await I_USDTieredSTO_Array[stoId].isOpen()); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); + let init_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + let tx; + let gasCost = BigNumber(0); + + if (isPoly && investment_POLY.gt(10)) { + tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE }); + gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); + console.log(`buyWithPOLY: ${investment_Token.div(10**18)} tokens for ${investment_POLY.div(10**18)} POLY by ${_investor}`.yellow); + } else if (isDai && investment_DAI.gt(10)) { + tx = await I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE }); + gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); + console.log(`buyWithUSD: ${investment_Token.div(10**18)} tokens for ${investment_DAI.div(10**18)} DAI by ${_investor}`.yellow); + } else if (investment_ETH.gt(0)) { + tx = await I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE }); + gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); + console.log(`buyWithETH: ${investment_Token.div(10**18)} tokens for ${investment_ETH.div(10**18)} ETH by ${_investor}`.yellow); + } + console.log(investment_POLY.toNumber()); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(_investor); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(_investor)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(_investor); + let final_InvestorDAIBal = await I_DaiToken.balanceOf(_investor); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_STODAIBal = await I_DaiToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(0); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(1); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(2); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + // console.log('init_TokenSupply: '+init_TokenSupply.div(10**18).toNumber()); + // console.log('final_TokenSupply: '+final_TokenSupply.div(10**18).toNumber()); + + if (isPoly) { + assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); + assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); + assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); + assert.closeTo(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), TOLERANCE, "Investor POLY Balance not changed as expected"); + assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); + assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); + assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, "STO POLY Balance not changed as expected"); + assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); + assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, "Raised ETH not changed as expected"); + assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), TOLERANCE, "Raised POLY not changed as expected"); + assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); + assert.closeTo(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), TOLERANCE, "Wallet POLY Balance not changed as expected"); + } else if (isDai) { + assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); + assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); + assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); + assert.closeTo(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), TOLERANCE, "Investor DAI Balance not changed as expected"); + assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); + assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); + assert.closeTo(final_STODAIBal.toNumber(), init_STODAIBal.toNumber(), TOLERANCE, "STO DAI Balance not changed as expected"); + assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); + assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, "Raised ETH not changed as expected"); + assert.closeTo(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), TOLERANCE, "Raised DAI not changed as expected"); + assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); + assert.closeTo(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), TOLERANCE, "Wallet DAI Balance not changed as expected"); + } else { + assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); + assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); + assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).sub(investment_ETH).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); + assert.closeTo(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), TOLERANCE, "Investor POLY Balance not changed as expected"); + assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); + assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); + assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, "STO POLY Balance not changed as expected"); + assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); + assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), TOLERANCE, "Raised ETH not changed as expected"); + assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), TOLERANCE, "Raised POLY not changed as expected"); + assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); + assert.closeTo(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), TOLERANCE, "Wallet POLY Balance not changed as expected"); + } + } + }); }); - }); }); function near(x, y, message) { - assert.isAtMost(x, y); + assert.isAtMost(x, y) + } diff --git a/test/r_concurrent_STO.js b/test/r_concurrent_STO.js index 78e7cc17b..f01a36436 100644 --- a/test/r_concurrent_STO.js +++ b/test/r_concurrent_STO.js @@ -10,7 +10,7 @@ const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); const DummySTO = artifacts.require('./DummySTO.sol'); const PreSaleSTOFactory = artifacts.require('./PreSaleSTOFactory.sol'); const PreSaleSTO = artifacts.require('./PreSaleSTO.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -26,182 +26,182 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('Concurrent STO', accounts => { - // Accounts variable declaration - let account_polymath; - let account_issuer; - let account_fundsReceiver; - let account_investor1; - let account_investor2; - let account_investor3; - - // Contract instance declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralPermissionManager; - let I_GeneralTransferManagerFactory; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_STFactory; - let I_MRProxied; - let I_STRProxied; - let I_SecurityTokenRegistry; - let I_SecurityToken; - let I_PolyToken; - let I_PolymathRegistry; - - // STO instance declaration - let I_CappedSTOFactory; - let I_DummySTOFactory; - let I_PreSaleSTOFactory; - let I_STO_Array = []; - - // Error message - let message = 'Transaction Should Fail!'; - - // Initial fees - const initRegFee = web3.utils.toWei('250'); - const STOSetupCost = 200 * Math.pow(10, 18); - - // Module keys - const transferManagerKey = 2; - const stoKey = 3; - - // Configure function signature for STO deployment - - const CappedSTOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const DummySTOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const PresaleSTOParameters = ['uint256']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - account_fundsReceiver = accounts[2]; - account_investor1 = accounts[3]; - account_investor2 = accounts[4]; - account_investor3 = accounts[5]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_issuer); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); + // Accounts variable declaration + let account_polymath; + let account_issuer; + let account_fundsReceiver; + let account_investor1; + let account_investor2; + let account_investor3; + + // Contract instance declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralPermissionManager; + let I_GeneralTransferManagerFactory; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_STFactory; + let I_MRProxied; + let I_STRProxied; + let I_SecurityTokenRegistry; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // STO instance declaration + let I_CappedSTOFactory; + let I_DummySTOFactory; + let I_PreSaleSTOFactory; + let I_STO_Array = []; + + // Error message + let message = "Transaction Should Fail!"; + + // Initial fees + const initRegFee = web3.utils.toWei("250"); + const STOSetupCost = 200 * Math.pow(10, 18); + + // Module keys + const transferManagerKey = 2; + const stoKey = 3; + + // Configure function signature for STO deployment + + const CappedSTOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + const DummySTOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const PresaleSTOParameters = ['uint256']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + account_fundsReceiver = accounts[2]; + account_investor1 = accounts[3]; + account_investor2 = accounts[4]; + account_investor3 = accounts[5] + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_issuer); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); - // STEP 3: Deploy the ModuleRegistry + // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // STEP 2: Deploy the GeneralTransferManagerFactory + // STEP 2: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - // STEP 3: Deploy the GeneralPermissionManagerFactory + // STEP 3: Deploy the GeneralPermissionManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - // STEP 4: Deploy the STO Factories + // STEP 4: Deploy the STO Factories - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); + I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CappedSTOFactory contract was not deployed' - ); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); - // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + // Step 8: Deploy the STFactory contract - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - // Step 9: Deploy the SecurityTokenRegistry contract + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + // Step 9: Deploy the SecurityTokenRegistry contract - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // STEP 5: Register the Modules with the ModuleRegistry contract + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // STEP 5: Register the Modules with the ModuleRegistry contract - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STO Factories - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + // (C) : Register the STO Factories + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -218,141 +218,148 @@ contract('Concurrent STO', accounts => { CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate Security Token', async () => { - // SecurityToken Details for funds raise Type ETH - const name = 'Team'; - const symbol = 'SAP'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.getTokens(initRegFee, account_issuer); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); - let tx = await I_STRProxied.registerTicker(account_issuer, symbol, name, { from: account_issuer }); - assert.equal(tx.logs[0].args._owner, account_issuer); - assert.equal(tx.logs[0].args._ticker, symbol); - }); - - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.getTokens(initRegFee, account_issuer); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_issuer }); - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); }); - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + describe("Generate Security Token", async() => { + // SecurityToken Details for funds raise Type ETH + const name = "Team"; + const symbol = "SAP"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.getTokens(initRegFee, account_issuer); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); + let tx = await I_STRProxied.registerTicker(account_issuer, symbol, name, { from : account_issuer }); + assert.equal(tx.logs[0].args._owner, account_issuer); + assert.equal(tx.logs[0].args._ticker, symbol); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.getTokens(initRegFee, account_issuer); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer}); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_issuer }); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(transferManagerKey, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + it("Should whitelist account_investor1", async() => { + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let canBuyFromSTO = true; + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + fromTime, + toTime, + expiryTime, + canBuyFromSTO, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); + }); }); - it('Should whitelist account_investor1', async () => { - let fromTime = latestTime(); - let toTime = latestTime() + duration.days(15); - let expiryTime = toTime + duration.days(100); - let canBuyFromSTO = true; - - let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, canBuyFromSTO, { - from: account_issuer, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor1, 'Failed in adding the investor in whitelist'); - }); - }); - - describe('Add STO and verify transfer', async () => { - it('Should attach STO modules up to the max number, then fail', async () => { - const MAX_MODULES = 10; - const startTime = latestTime() + duration.days(1); - const endTime = latestTime() + duration.days(90); - const cap = web3.utils.toWei('10000'); - const rate = 1000; - const fundRaiseType = [0]; - const budget = 0; - const maxCost = STOSetupCost; - const cappedBytesSig = encodeModuleCall(CappedSTOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, 'Hello']); - const presaleBytesSig = encodeModuleCall(PresaleSTOParameters, [endTime]); - - for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { - await I_PolyToken.getTokens(STOSetupCost, account_issuer); - await I_PolyToken.transfer(I_SecurityToken.address, STOSetupCost, { from: account_issuer }); - switch (STOIndex % 3) { - case 0: - // Capped STO - let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { - from: account_issuer - }); - assert.equal(tx1.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx1.logs[3].args._name), 'CappedSTO', `Wrong STO module added at index ${STOIndex}`); - I_STO_Array.push(CappedSTO.at(tx1.logs[3].args._module)); - break; - case 1: - // Dummy STO - let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { from: account_issuer }); - assert.equal(tx2.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx2.logs[3].args._name), 'DummySTO', `Wrong STO module added at index ${STOIndex}`); - I_STO_Array.push(DummySTO.at(tx2.logs[3].args._module)); - break; - case 2: - // Pre Sale STO - let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { - from: account_issuer - }); - assert.equal(tx3.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx3.logs[3].args._name), 'PreSaleSTO', `Wrong STO module added at index ${STOIndex}`); - I_STO_Array.push(PreSaleSTO.at(tx3.logs[3].args._module)); - break; - } - } - }); - - it('Should successfully invest in all modules attached', async () => { - const MAX_MODULES = 10; - await increaseTime(duration.days(2)); - for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { - switch (STOIndex % 3) { - case 0: - // Capped STO ETH - await I_STO_Array[STOIndex].buyTokens(account_investor1, { from: account_investor1, value: web3.utils.toWei('1', 'ether') }); - assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); - assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); - break; - case 1: - // Dummy STO - await I_STO_Array[STOIndex].generateTokens(account_investor1, web3.utils.toWei('1000'), { from: account_issuer }); - assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); - assert.equal( - (await I_STO_Array[STOIndex].investors.call(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), - 1000 - ); - break; - case 2: - // Pre Sale STO - await I_STO_Array[STOIndex].allocateTokens(account_investor1, web3.utils.toWei('1000'), web3.utils.toWei('1'), 0, { - from: account_issuer - }); - assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); - assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(1)).toString()), 0); - assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); - assert.equal( - (await I_STO_Array[STOIndex].investors.call(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), - 1000 - ); - break; - } - } + describe("Add STO and verify transfer", async() => { + + it("Should attach STO modules up to the max number, then fail", async() => { + const MAX_MODULES = 10; + const startTime = latestTime() + duration.days(1); + const endTime = latestTime() + duration.days(90); + const cap = web3.utils.toWei("10000"); + const rate = 1000; + const fundRaiseType = [0]; + const budget = 0; + const maxCost = STOSetupCost; + const cappedBytesSig = encodeModuleCall(CappedSTOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, 'Hello']); + const presaleBytesSig = encodeModuleCall(PresaleSTOParameters, [endTime]); + + for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { + await I_PolyToken.getTokens(STOSetupCost, account_issuer); + await I_PolyToken.transfer(I_SecurityToken.address, STOSetupCost, { from: account_issuer }); + switch (STOIndex % 3) { + case 0: + // Capped STO + let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { from: account_issuer }); + assert.equal(tx1.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx1.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); + I_STO_Array.push(CappedSTO.at(tx1.logs[3].args._module)); + break; + case 1: + // Dummy STO + let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { from: account_issuer }); + assert.equal(tx2.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx2.logs[3].args._name),"DummySTO",`Wrong STO module added at index ${STOIndex}`); + I_STO_Array.push(DummySTO.at(tx2.logs[3].args._module)); + break; + case 2: + // Pre Sale STO + let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { from: account_issuer }); + assert.equal(tx3.logs[3].args._type, stoKey, `Wrong module type added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx3.logs[3].args._name),"PreSaleSTO",`Wrong STO module added at index ${STOIndex}`); + I_STO_Array.push(PreSaleSTO.at(tx3.logs[3].args._module)); + break; + } + } + + }); + + it("Should successfully invest in all modules attached", async() => { + const MAX_MODULES = 10; + await increaseTime(duration.days(2)); + for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { + switch (STOIndex % 3) { + case 0: + // Capped STO ETH + await I_STO_Array[STOIndex].buyTokens(account_investor1, { from : account_investor1, value: web3.utils.toWei('1', 'ether') }); + assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); + assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); + break; + case 1: + // Dummy STO + await I_STO_Array[STOIndex].generateTokens(account_investor1, web3.utils.toWei('1000'), { from : account_issuer }); + assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); + assert.equal( + (await I_STO_Array[STOIndex].investors.call(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + break; + case 2: + // Pre Sale STO + await I_STO_Array[STOIndex].allocateTokens(account_investor1, web3.utils.toWei('1000'), web3.utils.toWei('1'), 0, { from : account_issuer }); + assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); + assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(1)).toString()), 0); + assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); + assert.equal( + (await I_STO_Array[STOIndex].investors.call(account_investor1)) + .dividedBy(new BigNumber(10).pow(18)) + .toNumber(), + 1000 + ); + break; + } + } + }); }); - }); }); diff --git a/test/s_v130_to_v140_upgrade.js b/test/s_v130_to_v140_upgrade.js index d710d17f0..4db50ca9f 100644 --- a/test/s_v130_to_v140_upgrade.js +++ b/test/s_v130_to_v140_upgrade.js @@ -1,12 +1,12 @@ const Web3 = require('web3'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port const BigNumber = require('bignumber.js'); import latestTime from './helpers/latestTime'; import { duration } from './helpers/utils'; import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const USDTieredSTOProxyFactory = artifacts.require('./USDTieredSTOProxyFactory.sol'); const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); @@ -27,235 +27,238 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const ManualApprovalTransferManagerFactory = artifacts.require('./ManualApprovalTransferManagerFactory.sol'); contract('Upgrade from v1.3.0 to v1.4.0', accounts => { - // Accounts Variable declaration - let POLYMATH; - let ISSUER1; - let ISSUER2; - let ISSUER3; - let MULTISIG; - - //const GAS_PRICE = 10000000000; // 10 GWEI - - let tx; - - // Initial fee for ticker registry and security token registry - const REGFEE = web3.utils.toWei('250'); - const STOSetupCost = 0; - - // Module key - const STOKEY = 3; - const TMKEY = 2; - - // SecurityToken 1 Details - const symbol1 = 'TOK1'; - const name1 = 'TOK1 Token'; - const tokenDetails1 = 'This is equity type of issuance'; - - //SecurityToken 2 Details - const symbol2 = 'TOK2'; - const name2 = 'TOK2 Token'; - const tokenDetails2 = 'This is equity type of issuance'; - - //SecurityToken 3 Details - const symbol3 = 'TOK3'; - const name3 = 'TOK3 Token'; - const tokenDetails3 = 'This is equity type of issuance'; - - // Contract Instance Declaration - let I_PolymathRegistry; - let I_PolyToken; - let I_DaiToken; - let I_ModuleRegistry; - let I_ModuleRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_FeatureRegistry; - let I_STFactory; - let I_MRProxied; - let I_STRProxied; - let I_STRProxiedNew; - - let I_SecurityTokenRegistry; - //let I_UpgradedSecurityTokenRegistry - - let I_SecurityToken1; - let I_SecurityToken2; - //let I_SecurityToken3; - - let I_USDTieredSTOFactory; - let I_USDTieredSTOProxyFactory; - let I_USDOracle; - let I_POLYOracle; - let I_USDTieredSTO; - - let I_CappedSTOFactory; - let I_UpgradedCappedSTOFactory; - let I_CappedSTO; - let I_ManualApprovalTransferManagerFactory; - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - // Prepare polymath network status - before(async () => { - // Accounts setup - POLYMATH = accounts[0]; - ISSUER1 = accounts[1]; - ISSUER2 = accounts[2]; - ISSUER3 = accounts[3]; - MULTISIG = accounts[4]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); - assert.notEqual( - I_PolymathRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'PolymathRegistry contract was not deployed' - ); - - // Step 1: Deploy the token Faucet - I_PolyToken = await PolyTokenFaucet.new({ from: POLYMATH }); - I_DaiToken = await PolyTokenFaucet.new({ from: POLYMATH }); - assert.notEqual(I_PolyToken.address.valueOf(), '0x0000000000000000000000000000000000000000', 'PolyToken contract was not deployed'); - tx = await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, 'PolyToken'); - assert.equal(tx.logs[0].args._newAddress, I_PolyToken.address); - - // STEP 2: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - tx = await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, 'ModuleRegistry'); - assert.equal(tx.logs[0].args._newAddress, I_ModuleRegistryProxy.address); - - // STEP 3: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); - - // STEP 4: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); - - // STEP 5: Deploy the CappedSTOFactory - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CappedSTOFactory contract was not deployed' - ); - - // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - REGFEE, - REGFEE, - I_PolyToken.address, - POLYMATH - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // 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_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_STRProxied.address, { from: POLYMATH }); - await I_MRProxied.updateFromRegistry({ from: POLYMATH }); - - // STEP 6: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - - // (C) : Register the CappedSTOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: POLYMATH }); - - // 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 13: Register tokens - // (A) : TOK1 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); - tx = await I_STRProxied.registerTicker(ISSUER1, symbol1, name1, { from: ISSUER1 }); - assert.equal(tx.logs[0].args._owner, ISSUER1); - assert.equal(tx.logs[0].args._ticker, symbol1); - - // (B) : TOK2 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); - tx = await I_STRProxied.registerTicker(ISSUER2, symbol2, name2, { from: ISSUER2 }); - assert.equal(tx.logs[0].args._owner, ISSUER2); - assert.equal(tx.logs[0].args._ticker, symbol2); - - // (C) : TOK3 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER3 }); - tx = await I_STRProxied.registerTicker(ISSUER3, symbol3, name3, { from: ISSUER3 }); - assert.equal(tx.logs[0].args._owner, ISSUER3); - assert.equal(tx.logs[0].args._ticker, symbol3); - - // Step 14: Deploy tokens - // (A) : TOK1 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); - let tx = await I_STRProxied.generateSecurityToken(name1, symbol1, tokenDetails1, false, { from: ISSUER1 }); - assert.equal(tx.logs[1].args._ticker, symbol1, "SecurityToken doesn't get deployed"); - I_SecurityToken1 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - // (B) : TOK2 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); - tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails2, false, { from: ISSUER2 }); - assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); - I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - // Printing all the contract addresses - console.log(` + // Accounts Variable declaration + let POLYMATH; + let ISSUER1; + let ISSUER2; + let ISSUER3; + let MULTISIG; + + //const GAS_PRICE = 10000000000; // 10 GWEI + + let tx; + + // Initial fee for ticker registry and security token registry + const REGFEE = web3.utils.toWei("250"); + const STOSetupCost = 0; + + // Module key + const STOKEY = 3; + const TMKEY = 2; + + // SecurityToken 1 Details + const symbol1 = "TOK1"; + const name1 = "TOK1 Token"; + const tokenDetails1 = "This is equity type of issuance"; + + //SecurityToken 2 Details + const symbol2 = "TOK2"; + const name2 = "TOK2 Token"; + const tokenDetails2 = "This is equity type of issuance"; + + //SecurityToken 3 Details + const symbol3 = "TOK3"; + const name3 = "TOK3 Token"; + const tokenDetails3 = "This is equity type of issuance"; + + // Contract Instance Declaration + let I_PolymathRegistry; + let I_PolyToken; + let I_DaiToken; + let I_ModuleRegistry; + let I_ModuleRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_FeatureRegistry; + let I_STFactory; + let I_MRProxied; + let I_STRProxied; + let I_STRProxiedNew; + + let I_SecurityTokenRegistry; + //let I_UpgradedSecurityTokenRegistry + + let I_SecurityToken1; + let I_SecurityToken2; + //let I_SecurityToken3; + + let I_USDTieredSTOFactory; + let I_USDTieredSTOProxyFactory + let I_USDOracle; + let I_POLYOracle; + let I_USDTieredSTO; + + let I_CappedSTOFactory; + let I_UpgradedCappedSTOFactory; + let I_CappedSTO; + let I_ManualApprovalTransferManagerFactory; + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + // Prepare polymath network status + before(async() => { + // Accounts setup + POLYMATH = accounts[0]; + ISSUER1 = accounts[1]; + ISSUER2 = accounts[2]; + ISSUER3 = accounts[3]; + MULTISIG = accounts[4]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); + assert.notEqual( + I_PolymathRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "PolymathRegistry contract was not deployed" + ); + + // Step 1: Deploy the token Faucet + I_PolyToken = await PolyTokenFaucet.new({from: POLYMATH}); + I_DaiToken = await PolyTokenFaucet.new({from: POLYMATH}); + assert.notEqual( + I_PolyToken.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "PolyToken contract was not deployed" + ); + tx = await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) + assert.equal(tx.logs[0].args._nameKey, "PolyToken"); + assert.equal(tx.logs[0].args._newAddress, I_PolyToken.address); + + // STEP 2: Deploy the ModuleRegistry + I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + tx = await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); + assert.equal(tx.logs[0].args._nameKey, "ModuleRegistry"); + assert.equal(tx.logs[0].args._newAddress, I_ModuleRegistryProxy.address); + + // STEP 3: Deploy the GeneralTransferManagerFactory + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 4: Deploy the GeneralDelegateManagerFactory + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 5: Deploy the CappedSTOFactory + I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); + + // Step 8: Deploy the STFactory contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 9: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 10: update the registries addresses from the PolymathRegistry contract + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // 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_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_STRProxied.address, {from: POLYMATH}); + await I_MRProxied.updateFromRegistry({from: POLYMATH}); + + // STEP 6: Register the Modules with the ModuleRegistry contract + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); + + // (C) : Register the CappedSTOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: POLYMATH }); + + // 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 13: Register tokens + // (A) : TOK1 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); + tx = await I_STRProxied.registerTicker(ISSUER1, symbol1, name1, { from : ISSUER1 }); + assert.equal(tx.logs[0].args._owner, ISSUER1); + assert.equal(tx.logs[0].args._ticker, symbol1); + + // (B) : TOK2 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); + tx = await I_STRProxied.registerTicker(ISSUER2, symbol2, name2, { from : ISSUER2 }); + assert.equal(tx.logs[0].args._owner, ISSUER2); + assert.equal(tx.logs[0].args._ticker, symbol2); + + // (C) : TOK3 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER3 }); + tx = await I_STRProxied.registerTicker(ISSUER3, symbol3, name3, { from : ISSUER3 }); + assert.equal(tx.logs[0].args._owner, ISSUER3); + assert.equal(tx.logs[0].args._ticker, symbol3); + + // Step 14: Deploy tokens + // (A) : TOK1 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1}); + let tx = await I_STRProxied.generateSecurityToken(name1, symbol1, tokenDetails1, false, { from: ISSUER1 }); + assert.equal(tx.logs[1].args._ticker, symbol1, "SecurityToken doesn't get deployed"); + I_SecurityToken1 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + // (B) : TOK2 + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2}); + tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails2, false, { from: ISSUER2 }); + assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); + I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -272,111 +275,113 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { SecurityToken TOK2: ${I_SecurityToken2.address} ----------------------------------------------------------------------------- `); - }); - - describe('USDTieredSTOFactory deploy', async () => { - // Step 1: Deploy Oracles - // 1a - Deploy POLY Oracle - it('Should successfully deploy POLY Oracle and register on PolymathRegistry', async () => { - I_POLYOracle = await PolyOracle.new({ from: POLYMATH, value: web3.utils.toWei('1') }); - console.log(I_POLYOracle.address); - assert.notEqual(I_POLYOracle.address.valueOf(), '0x0000000000000000000000000000000000000000', 'POLYOracle contract was not deployed'); - tx = await I_PolymathRegistry.changeAddress('PolyUsdOracle', I_POLYOracle.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, 'PolyUsdOracle'); - assert.equal(tx.logs[0].args._newAddress, I_POLYOracle.address); - }); - // 1b - Deploy ETH Oracle - it('Should successfully deploy ETH Oracle and register on PolymathRegistry', async () => { - I_USDOracle = await ETHOracle.new('0x216d678c14be600cb88338e763bb57755ca2b1cf', '0x0000000000000000000000000000000000000000', 'ETH', { - from: POLYMATH - }); - assert.notEqual(I_USDOracle.address.valueOf(), '0x0000000000000000000000000000000000000000', 'USDOracle contract was not deployed'); - tx = await I_PolymathRegistry.changeAddress('EthUsdOracle', I_USDOracle.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, 'EthUsdOracle'); - assert.equal(tx.logs[0].args._newAddress, I_USDOracle.address); - }); - }); - - describe('USDTieredSTOFactory deploy', async () => { - // Step 1: Deploy USDTieredSTOFactory\ - it('Should successfully deploy USDTieredSTOFactory', async () => { - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new(); - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { - from: POLYMATH - }); - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'USDTieredSTOFactory contract was not deployed' - ); - let setupCost = await I_USDTieredSTOFactory.setupCost({ from: POLYMATH }); - assert.equal(setupCost, STOSetupCost); - }); - // Step 2: Register and verify - it('Should successfully register and verify USDTieredSTOFactory contract', async () => { - let tx = await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); - tx = await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); - assert.isTrue(tx.logs[0].args._verified); - }); - }); - - describe('CappedSTOFactory deploy', async () => { - // Step 1: Deploy new CappedSTOFactory - it('Should successfully deploy CappedSTOFactory', async () => { - I_UpgradedCappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_UpgradedCappedSTOFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'CappedSTOFactory contract was not deployed' - ); - let setupCost = await I_UpgradedCappedSTOFactory.setupCost({ from: POLYMATH }); - assert.equal(setupCost, STOSetupCost); }); - // Step 2: Register and verify - it('Should successfully register and verify new CappedSTOFactory contract', async () => { - let tx = await I_MRProxied.registerModule(I_UpgradedCappedSTOFactory.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); - tx = await I_MRProxied.verifyModule(I_UpgradedCappedSTOFactory.address, true, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); - assert.isTrue(tx.logs[0].args._verified); + describe("USDTieredSTOFactory deploy", async() => { + // Step 1: Deploy Oracles + // 1a - Deploy POLY Oracle + it("Should successfully deploy POLY Oracle and register on PolymathRegistry", async() => { + I_POLYOracle = await PolyOracle.new({ from: POLYMATH, value: web3.utils.toWei("1")}); + console.log(I_POLYOracle.address); + assert.notEqual( + I_POLYOracle.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "POLYOracle contract was not deployed", + ); + tx = await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._nameKey, "PolyUsdOracle"); + assert.equal(tx.logs[0].args._newAddress, I_POLYOracle.address); + }); + // 1b - Deploy ETH Oracle + it("Should successfully deploy ETH Oracle and register on PolymathRegistry", async() => { + I_USDOracle = await ETHOracle.new("0x216d678c14be600cb88338e763bb57755ca2b1cf", "0x0000000000000000000000000000000000000000", "ETH", { from: POLYMATH }); + assert.notEqual( + I_USDOracle.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "USDOracle contract was not deployed", + ); + tx = await I_PolymathRegistry.changeAddress("EthUsdOracle", I_USDOracle.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._nameKey, "EthUsdOracle"); + assert.equal(tx.logs[0].args._newAddress, I_USDOracle.address); + }); }); - // Step 3: Unverify old CappedSTOFactory - it('Should successfully unverify old CappedSTOFactory contract', async () => { - let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory.address, false, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory.address); - assert.isFalse(tx.logs[0].args._verified); + describe("USDTieredSTOFactory deploy", async() => { + // Step 1: Deploy USDTieredSTOFactory\ + it("Should successfully deploy USDTieredSTOFactory", async() => { + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new(); + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: POLYMATH }); + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "USDTieredSTOFactory contract was not deployed" + ); + let setupCost = await I_USDTieredSTOFactory.setupCost({ from: POLYMATH }); + assert.equal(setupCost, STOSetupCost); + }); + // Step 2: Register and verify + it("Should successfully register and verify USDTieredSTOFactory contract", async() => { + let tx = await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); + tx = await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); + assert.isTrue(tx.logs[0].args._verified); + }); }); - }); - - describe('ManualApprovalTransferManagerFactory deploy', async () => { - // Step 1: Deploy new ManualApprovalTransferManager - it('Should successfully deploy ManualApprovalTransferManagerFactory', async () => { - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: POLYMATH - }); - assert.notEqual( - I_ManualApprovalTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'ManualApprovalTransferManagerFactory contract was not deployed' - ); + + describe("CappedSTOFactory deploy", async() => { + // Step 1: Deploy new CappedSTOFactory + it("Should successfully deploy CappedSTOFactory", async() => { + I_UpgradedCappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_UpgradedCappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); + let setupCost = await I_UpgradedCappedSTOFactory.setupCost({ from: POLYMATH }); + assert.equal(setupCost, STOSetupCost); + }); + + // Step 2: Register and verify + it("Should successfully register and verify new CappedSTOFactory contract", async() => { + let tx = await I_MRProxied.registerModule(I_UpgradedCappedSTOFactory.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); + tx = await I_MRProxied.verifyModule(I_UpgradedCappedSTOFactory.address, true, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); + assert.isTrue(tx.logs[0].args._verified); + }); + + // Step 3: Unverify old CappedSTOFactory + it("Should successfully unverify old CappedSTOFactory contract", async() => { + let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory.address, false, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory.address); + assert.isFalse(tx.logs[0].args._verified); + }); }); - // Step 2: Register and verify - it('Should successfully register and verify new ManualApprovalTransferManagerFactory contract', async () => { - let tx = await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); - tx = await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: POLYMATH }); - assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); - assert.isTrue(tx.logs[0].args._verified); + describe("ManualApprovalTransferManagerFactory deploy", async() => { + // Step 1: Deploy new ManualApprovalTransferManager + it("Should successfully deploy ManualApprovalTransferManagerFactory", async() => { + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + assert.notEqual( + I_ManualApprovalTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ManualApprovalTransferManagerFactory contract was not deployed" + ); + }); + + // Step 2: Register and verify + it("Should successfully register and verify new ManualApprovalTransferManagerFactory contract", async() => { + let tx = await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); + tx = await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: POLYMATH }); + assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); + assert.isTrue(tx.logs[0].args._verified); + }); }); - }); - describe('Change ownerships', async () => { - /* + describe("Change ownerships", async() => { + /* // Step 1: SecurityTokenRegistry it("Should successfully change ownership of new SecurityTokenRegistry contract", async() => { let tx = await I_STRProxiedNew.transferOwnership(MULTISIG, { from: POLYMATH }); @@ -385,134 +390,112 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); */ - // Step 2: Oracles - it('Should successfully change ownership of both Oracles contract', async () => { - let tx = await I_USDOracle.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous ETH Oracle owner was not Polymath account'); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New ETH Oracle owner is not Multisig account'); + // Step 2: Oracles + it("Should successfully change ownership of both Oracles contract", async() => { + let tx = await I_USDOracle.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous ETH Oracle owner was not Polymath account"); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New ETH Oracle owner is not Multisig account"); - tx = await I_POLYOracle.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous POLY Oracle owner was not Polymath account'); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New POLY Oracle owner is not Multisig account'); - }); + tx = await I_POLYOracle.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous POLY Oracle owner was not Polymath account"); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New POLY Oracle owner is not Multisig account"); + }); - // Step 3: USDTieredSTOFactory - it('Should successfully change ownership of USDTieredSTOFactory contract', async () => { - let tx = await I_USDTieredSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous USDTieredSTOFactory owner was not Polymath account'); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New USDTieredSTOFactory owner is not Multisig account'); - }); + // Step 3: USDTieredSTOFactory + it("Should successfully change ownership of USDTieredSTOFactory contract", async() => { + let tx = await I_USDTieredSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous USDTieredSTOFactory owner was not Polymath account"); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New USDTieredSTOFactory owner is not Multisig account"); + }); - // Step 3: CappedSTOFactory - it('Should successfully change ownership of CappedSTOFactory contract', async () => { - let tx = await I_UpgradedCappedSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous USDTieredSTOFactory owner was not Polymath account'); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New USDTieredSTOFactory owner is not Multisig account'); - }); + // Step 3: CappedSTOFactory + it("Should successfully change ownership of CappedSTOFactory contract", async() => { + let tx = await I_UpgradedCappedSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous USDTieredSTOFactory owner was not Polymath account"); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New USDTieredSTOFactory owner is not Multisig account"); + }); - // Step 4: ManualApprovalTransferManagerFactory - it('Should successfully change ownership of ManualApprovalTransferManagerFactory contract', async () => { - let tx = await I_ManualApprovalTransferManagerFactory.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, 'Previous ManualApprovalTransferManagerFactory owner was not Polymath account'); - assert.equal(tx.logs[0].args.newOwner, MULTISIG, 'New ManualApprovalTransferManagerFactory owner is not Multisig account'); - }); - }); - - describe('Polymath network status post migration', async () => { - // Launch STO for TOK1 - it('Should successfully launch USDTieredSTO for first security token', async () => { - let _startTime = latestTime() + duration.days(1); - let _endTime = _startTime + duration.days(180); - let _ratePerTier = [BigNumber(0.1).mul(10 ** 18), BigNumber(0.15).mul(10 ** 18), BigNumber(0.2).mul(10 ** 18)]; - let _ratePerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; - let _tokensPerTierTotal = [BigNumber(100).mul(10 ** 18), BigNumber(200).mul(10 ** 18), BigNumber(300).mul(10 ** 18)]; - let _tokensPerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; - let _nonAccreditedLimitUSD = BigNumber(100).mul(10 ** 18); - let _minimumInvestmentUSD = BigNumber(5).mul(10 ** 18); - let _fundRaiseTypes = [0, 1]; - let _wallet = ISSUER1; - let _reserveWallet = ISSUER1; - let _usdToken = I_DaiToken.address; - - let config = [ - _startTime, - _endTime, - _ratePerTier, - _ratePerTierDiscountPoly, - _tokensPerTierTotal, - _tokensPerTierDiscountPoly, - _nonAccreditedLimitUSD, - _minimumInvestmentUSD, - _fundRaiseTypes, - _wallet, - _reserveWallet, - _usdToken - ]; - - let functionSignature = { - name: 'configure', - type: 'function', - inputs: [ - { - type: 'uint256', - name: '_startTime' - }, - { - type: 'uint256', - name: '_endTime' - }, - { - type: 'uint256[]', - name: '_ratePerTier' - }, - { - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - }, - { - type: 'uint256[]', - name: '_tokensPerTier' - }, - { - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - }, - { - type: 'uint256', - name: '_nonAccreditedLimitUSD' - }, - { - type: 'uint256', - name: '_minimumInvestmentUSD' - }, - { - type: 'uint8[]', - name: '_fundRaiseTypes' - }, - { - type: 'address', - name: '_wallet' - }, - { - type: 'address', - name: '_reserveWallet' - }, - { - type: 'address', - name: '_usdToken' - } - ] - }; - - let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - - let tx = await I_SecurityToken1.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER1 }); - assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'USDTieredSTO', 'USDTieredSTOFactory module was not added'); - I_USDTieredSTO = USDTieredSTO.at(tx.logs[2].args._module); + // Step 4: ManualApprovalTransferManagerFactory + it("Should successfully change ownership of ManualApprovalTransferManagerFactory contract", async() => { + let tx = await I_ManualApprovalTransferManagerFactory.transferOwnership(MULTISIG, { from: POLYMATH }); + assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous ManualApprovalTransferManagerFactory owner was not Polymath account"); + assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New ManualApprovalTransferManagerFactory owner is not Multisig account"); + }); }); - /* + describe("Polymath network status post migration", async() => { + // Launch STO for TOK1 + it("Should successfully launch USDTieredSTO for first security token", async() => { + let _startTime = latestTime() + duration.days(1); + let _endTime = _startTime + duration.days(180); + let _ratePerTier = [BigNumber(0.1).mul(10**18), BigNumber(0.15).mul(10**18), BigNumber(0.2).mul(10**18)]; + let _ratePerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; + let _tokensPerTierTotal = [BigNumber(100).mul(10**18), BigNumber(200).mul(10**18), BigNumber(300).mul(10**18)]; + let _tokensPerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; + let _nonAccreditedLimitUSD = BigNumber(100).mul(10**18); + let _minimumInvestmentUSD = BigNumber(5).mul(10**18); + let _fundRaiseTypes = [0, 1]; + let _wallet = ISSUER1; + let _reserveWallet = ISSUER1; + let _usdToken = I_DaiToken.address; + + let config = [ + _startTime, _endTime, _ratePerTier, _ratePerTierDiscountPoly, _tokensPerTierTotal, + _tokensPerTierDiscountPoly, _nonAccreditedLimitUSD, _minimumInvestmentUSD, + _fundRaiseTypes, _wallet, _reserveWallet, _usdToken + ]; + + let functionSignature = { + name: 'configure', + type: 'function', + inputs: [{ + type: 'uint256', + name: '_startTime' + },{ + type: 'uint256', + name: '_endTime' + },{ + type: 'uint256[]', + name: '_ratePerTier' + },{ + type: 'uint256[]', + name: '_ratePerTierDiscountPoly' + },{ + type: 'uint256[]', + name: '_tokensPerTier' + },{ + type: 'uint256[]', + name: '_tokensPerTierDiscountPoly' + },{ + type: 'uint256', + name: '_nonAccreditedLimitUSD' + },{ + type: 'uint256', + name: '_minimumInvestmentUSD' + },{ + type: 'uint8[]', + name: '_fundRaiseTypes' + },{ + type: 'address', + name: '_wallet' + },{ + type: 'address', + name: '_reserveWallet' + },{ + type: 'address', + name: '_usdToken' + }] + }; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + + let tx = await I_SecurityToken1.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER1 }); + assert.equal(tx.logs[2].args._type, STOKEY, "USDTieredSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + I_USDTieredSTO = USDTieredSTO.at(tx.logs[2].args._module); + }); + + /* // Deploy TOK3 it("Should successfully deploy third security token", async() => { await I_PolyToken.approve(I_STRProxiedNew.address, REGFEE, { from: ISSUER3}); @@ -522,32 +505,28 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); */ - // Launch NewCappedSTO for TOK2 - it('Should successfully launch CappedSTO for third security token', async () => { - let startTime = latestTime() + duration.days(1); - let endTime = startTime + duration.days(30); - let cap = web3.utils.toWei('500000'); - let rate = 1000; - let fundRaiseType = 0; - let fundsReceiver = ISSUER3; + // Launch NewCappedSTO for TOK2 + it("Should successfully launch CappedSTO for third security token", async() => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + let cap = web3.utils.toWei("500000"); + let rate = 1000; + let fundRaiseType = 0; + let fundsReceiver = ISSUER3; - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [fundRaiseType], fundsReceiver]); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [fundRaiseType], fundsReceiver]); - let tx = await I_SecurityToken2.addModule(I_UpgradedCappedSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER2 }); - assert.equal(tx.logs[2].args._type, STOKEY, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name), 'CappedSTO', 'CappedSTOFactory module was not added'); - }); + let tx = await I_SecurityToken2.addModule(I_UpgradedCappedSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER2 }); + assert.equal(tx.logs[2].args._type, STOKEY, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"CappedSTO","CappedSTOFactory module was not added"); + }); - // Attach ManualApprovalTransferManager module for TOK2 - it('Should successfully attach the ManualApprovalTransferManagerFactory with the second token', async () => { - const tx = await I_SecurityToken2.addModule(I_ManualApprovalTransferManagerFactory.address, '', 0, 0, { from: ISSUER2 }); - assert.equal(tx.logs[2].args._type.toNumber(), TMKEY, "ManualApprovalTransferManagerFactory doesn't get deployed"); - assert.equal( - web3.utils.toUtf8(tx.logs[2].args._name), - 'ManualApprovalTransferManager', - 'ManualApprovalTransferManagerFactory module was not added' - ); - I_ManualApprovalTransferManagerFactory = ManualApprovalTransferManagerFactory.at(tx.logs[2].args._module); + // Attach ManualApprovalTransferManager module for TOK2 + it("Should successfully attach the ManualApprovalTransferManagerFactory with the second token", async () => { + const tx = await I_SecurityToken2.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: ISSUER2 }); + assert.equal(tx.logs[2].args._type.toNumber(), TMKEY, "ManualApprovalTransferManagerFactory doesn't get deployed"); + assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManagerFactory module was not added"); + I_ManualApprovalTransferManagerFactory = ManualApprovalTransferManagerFactory.at(tx.logs[2].args._module); + }); }); - }); }); diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 65513d600..91ef0c974 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -2,300 +2,292 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); -const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); -const SecurityTokenRegistryMock = artifacts.require('./SecurityTokenRegistryMock.sol'); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); +const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); +const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); const OwnedUpgradeabilityProxy = artifacts.require('./OwnedUpgradeabilityProxy.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol') +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol') const STFactory = artifacts.require('./STFactory.sol'); const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol') const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port - -contract('SecurityTokenRegistryProxy', accounts => { - let I_SecurityTokenRegistry; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_SecurityTokenRegistryMock; - let I_STFactory; - let I_PolymathRegistry; - let I_ModuleRegistryProxy; - let I_PolyToken; - let I_STRProxied; - let I_MRProxied; - let I_SecurityToken; - let I_ModuleRegistry; - let I_FeatureRegistry; - - let account_polymath; - let account_temp; - let token_owner; - let account_polymath_new; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - const version = '1.0.0'; - const message = 'Transaction Should Fail!'; - - // SecurityToken Details for funds raise Type ETH - const name = 'Team'; - const symbol = 'SAP'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - const transferManagerKey = 2; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - async function readStorage(contractAddress, slot) { - return await web3.eth.getStorageAt(contractAddress, slot); - } - - before(async () => { - account_polymath = accounts[0]; - account_temp = accounts[1]; - token_owner = accounts[2]; - account_polymath_new = accounts[3]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - // STEP 3: Deploy the ModuleRegistry +contract ("SecurityTokenRegistryProxy", accounts => { - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // STEP 4: Deploy the GeneralTransferManagerFactory + let I_SecurityTokenRegistry; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_SecurityTokenRegistryMock; + let I_STFactory; + let I_PolymathRegistry; + let I_ModuleRegistryProxy; + let I_PolyToken; + let I_STRProxied; + let I_MRProxied; + let I_SecurityToken; + let I_ModuleRegistry; + let I_FeatureRegistry; - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + let account_polymath; + let account_temp; + let token_owner; + let account_polymath_new; - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + const version = "1.0.0"; + const message = "Transaction Should Fail!"; - // Register the Modules with the ModuleRegistry contract + // SecurityToken Details for funds raise Type ETH + const name = "Team"; + const symbol = "SAP"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; - // Step 3: Deploy the STFactory contract + const transferManagerKey = 2; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + async function readStorage(contractAddress, slot) { + return await web3.eth.getStorageAt(contractAddress, slot); + } - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + before(async() => { + account_polymath = accounts[0]; + account_temp = accounts[1]; + token_owner = accounts[2]; + account_polymath_new = accounts[3]; - // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + // ----------- POLYMATH NETWORK Configuration ------------ - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // Step 2: Deploy the FeatureRegistry - // Printing all the contract addresses - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - ----------------------------------------------------------------------------- - `); - }); - - describe('Attach the implementation address', async () => { - // Storage - // __version -- index 11 - // __implementation -- index 12 - // __upgradeabilityOwner -- index 13 - - it('Should attach the implementation and version', async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address); - assert.equal( - web3.utils - .toAscii(await readStorage(c.address, 11)) - .replace(/\u0000/g, '') - .replace(/\n/, ''), - '1.0.0' - ); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - }); - - it('Verify the initialize data', async () => { - assert.equal( - (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('expiryLimit'))).toNumber(), - 60 * 24 * 60 * 60, - 'Should equal to 60 days' - ); - assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3('tickerRegFee'))).toNumber(), web3.utils.toWei('250')); - }); - }); - - describe('Feed some data in storage', async () => { - it('Register the ticker', async () => { - await I_PolyToken.getTokens(web3.utils.toWei('1000'), token_owner); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner, 'Owner should be the same as registered with the ticker'); - assert.equal(tx.logs[0].args._ticker, symbol, 'Same as the symbol registered in the registerTicker function call'); - }); + // STEP 3: Deploy the ModuleRegistry - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + // STEP 4: Deploy the GeneralTransferManagerFactory - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name), 'GeneralTransferManager'); - }); - }); - - describe('Upgrade the imlplementation address', async () => { - it('Should upgrade the version and implementation address -- fail bad owner', async () => { - I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({ from: account_polymath }); - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryMock.address, { from: account_temp })); - }); + // Register the Modules with the ModuleRegistry contract - it('Should upgrade the version and implementation address -- Implementaion address should be a contract address', async () => { - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', account_temp, { from: account_polymath })); - }); - it('Should upgrade the version and implementation address -- Implemenation address should not be 0x', async () => { - await catchRevert( - I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', '0x00000000000000000000000000000000000000', { from: account_polymath }) - ); - }); + // Step 3: Deploy the STFactory contract - it('Should upgrade the version and implementation address -- Implemenation address should not be the same address', async () => { - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistry.address, { from: account_polymath })); - }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - it('Should upgrade the version and implementation address -- same version as previous is not allowed', async () => { - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('1.0.0', I_SecurityTokenRegistryMock.address, { from: account_polymath })); - }); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - it('Should upgrade the version and implementation address -- empty version string is not allowed', async () => { - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo('', I_SecurityTokenRegistryMock.address, { from: account_polymath })); - }); + // Step 4: Deploy the SecurityTokenRegistry + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - it('Should upgrade the version and the implementation address successfully', async () => { - await I_SecurityTokenRegistryProxy.upgradeTo('1.1.0', I_SecurityTokenRegistryMock.address, { from: account_polymath }); - let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal( - web3.utils - .toAscii(await readStorage(c.address, 11)) - .replace(/\u0000/g, '') - .replace(/\n/, ''), - '1.1.0', - 'Version mis-match' - ); - assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistryMock.address, 'Implemnted address is not matched'); - I_STRProxied = await SecurityTokenRegistryMock.at(I_SecurityTokenRegistryProxy.address); - }); - }); - - describe('Execute functionality of the implementation contract on the earlier storage', async () => { - it('Should get the previous data', async () => { - let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); - let _data = await I_STRProxied.getSecurityTokenData.call(_tokenAddress); - assert.equal(_data[0], symbol, 'Symbol should match with registered symbol'); - assert.equal(_data[1], token_owner, 'Owner should be the deployer of token'); - assert.equal(_data[2], tokenDetails, 'Token details should matched with deployed ticker'); - }); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - it('Should alter the old storage', async () => { - await I_STRProxied.changeTheDeployedAddress(symbol, account_temp, { from: account_polymath }); - let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); - assert.equal(_tokenAddress, account_temp, 'Should match with the changed address'); - }); - }); - describe('Transfer the ownership of the proxy contract', async () => { - it('Should change the ownership of the contract -- because of bad owner', async () => { - await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_temp })); - }); + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} - it('Should change the ownership of the contract -- new address should not be 0x', async () => { - await catchRevert( - I_SecurityTokenRegistryProxy.transferProxyOwnership('0x00000000000000000000000000000000000000', { from: account_polymath }) - ); + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + ----------------------------------------------------------------------------- + `); }); - it('Should change the ownership of the contract', async () => { - await I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_polymath }); - let _currentOwner = await I_SecurityTokenRegistryProxy.proxyOwner.call({ from: account_polymath_new }); - assert.equal(_currentOwner, account_polymath_new, 'Should equal to the new owner'); + describe("Attach the implementation address", async() => { + + // Storage + // __version -- index 11 + // __implementation -- index 12 + // __upgradeabilityOwner -- index 13 + + it("Should attach the implementation and version", async() => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); + assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address); + assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.0.0"); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + }); + + it("Verify the initialize data", async() => { + assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))).toNumber(), 60*24*60*60, "Should equal to 60 days"); + assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("tickerRegFee"))).toNumber(), web3.utils.toWei("250")); + }); + + }) + + describe("Feed some data in storage", async() => { + + it("Register the ticker", async() => { + await I_PolyToken.getTokens(web3.utils.toWei("1000"), token_owner); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner, "Owner should be the same as registered with the ticker"); + assert.equal(tx.logs[0].args._ticker, symbol, "Same as the symbol registered in the registerTicker function call"); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), transferManagerKey); + assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + }); + }) + + describe("Upgrade the imlplementation address", async() => { + + it("Should upgrade the version and implementation address -- fail bad owner", async() => { + + I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({from: account_polymath}); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_temp})); + }); + + it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { + + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { + + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { + + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistry.address, {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { + + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.0.0", I_SecurityTokenRegistryMock.address, {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { + + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("", I_SecurityTokenRegistryMock.address, {from: account_polymath})); + }); + + it("Should upgrade the version and the implementation address successfully", async() => { + await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_polymath}); + let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); + assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.1.0", "Version mis-match"); + assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistryMock.address, "Implemnted address is not matched"); + I_STRProxied = await SecurityTokenRegistryMock.at(I_SecurityTokenRegistryProxy.address); + }); }); - it('Should change the implementation contract and version by the new owner', async () => { - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - await I_SecurityTokenRegistryProxy.upgradeTo('1.2.0', I_SecurityTokenRegistry.address, { from: account_polymath_new }); - let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal( - web3.utils - .toAscii(await readStorage(c.address, 11)) - .replace(/\u0000/g, '') - .replace(/\n/, ''), - '1.2.0', - 'Version mis-match' - ); - assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address, 'Implemnted address is not matched'); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - }); - }); -}); + describe("Execute functionality of the implementation contract on the earlier storage", async() => { + + it("Should get the previous data", async() => { + let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); + let _data = await I_STRProxied.getSecurityTokenData.call(_tokenAddress); + assert.equal(_data[0], symbol, "Symbol should match with registered symbol"); + assert.equal(_data[1], token_owner, "Owner should be the deployer of token"); + assert.equal(_data[2], tokenDetails, "Token details should matched with deployed ticker"); + }); + + it("Should alter the old storage", async() => { + await I_STRProxied.changeTheDeployedAddress(symbol, account_temp, {from: account_polymath}); + let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); + assert.equal(_tokenAddress, account_temp, "Should match with the changed address"); + }); + }) + + describe("Transfer the ownership of the proxy contract", async() => { + + it("Should change the ownership of the contract -- because of bad owner", async()=> { + + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); + }); + + it("Should change the ownership of the contract -- new address should not be 0x", async()=> { + + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); + }); + + it("Should change the ownership of the contract", async()=> { + await I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_polymath}); + let _currentOwner = await I_SecurityTokenRegistryProxy.proxyOwner.call({from: account_polymath_new}); + assert.equal(_currentOwner, account_polymath_new, "Should equal to the new owner"); + }); + + it("Should change the implementation contract and version by the new owner", async() => { + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath}); + await I_SecurityTokenRegistryProxy.upgradeTo("1.2.0", I_SecurityTokenRegistry.address, {from: account_polymath_new}); + let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); + assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.2.0", "Version mis-match"); + assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address, "Implemnted address is not matched"); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + }); + }) + + +}) diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index 7674b6e5c..67e6a57a0 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -2,114 +2,118 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from './hel import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); -const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); +const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); -const MockModuleRegistry = artifacts.require('./MockModuleRegistry.sol'); +const MockModuleRegistry = artifacts.require("./MockModuleRegistry.sol"); const OwnedUpgradeabilityProxy = artifacts.require('./OwnedUpgradeabilityProxy.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol') +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol') const STFactory = artifacts.require('./STFactory.sol'); const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol') const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port - -contract('ModuleRegistryProxy', accounts => { - let I_SecurityTokenRegistry; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManagerfactory; - let I_MockModuleRegistry; - let I_STFactory; - let I_PolymathRegistry; - let I_ModuleRegistryProxy; - let I_PolyToken; - let I_STRProxied; - let I_MRProxied; - let I_SecurityToken; - let I_ModuleRegistry; - let I_FeatureRegistry; - - let account_polymath; - let account_temp; - let token_owner; - let account_polymath_new; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - const version = '1.0.0'; - const message = 'Transaction Should Fail!'; - - // SecurityToken Details for funds raise Type ETH - const name = 'Team'; - const symbol = 'SAP'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - - const transferManagerKey = 2; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - async function readStorage(contractAddress, slot) { - return await web3.eth.getStorageAt(contractAddress, slot); - } - - before(async () => { - account_polymath = accounts[0]; - account_temp = accounts[1]; - token_owner = accounts[2]; - account_polymath_new = accounts[3]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); - - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // Printing all the contract addresses - console.log(` +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract ("ModuleRegistryProxy", accounts => { + + + let I_SecurityTokenRegistry; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManagerfactory; + let I_MockModuleRegistry; + let I_STFactory; + let I_PolymathRegistry; + let I_ModuleRegistryProxy; + let I_PolyToken; + let I_STRProxied; + let I_MRProxied; + let I_SecurityToken; + let I_ModuleRegistry; + let I_FeatureRegistry; + + let account_polymath; + let account_temp; + let token_owner; + let account_polymath_new; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + const version = "1.0.0"; + const message = "Transaction Should Fail!"; + + // SecurityToken Details for funds raise Type ETH + const name = "Team"; + const symbol = "SAP"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + + const transferManagerKey = 2; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + async function readStorage(contractAddress, slot) { + return await web3.eth.getStorageAt(contractAddress, slot); + } + + before(async() => { + account_polymath = accounts[0]; + account_temp = accounts[1]; + token_owner = accounts[2]; + account_polymath_new = accounts[3]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // Step 4: Deploy the SecurityTokenRegistry + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -120,167 +124,161 @@ contract('ModuleRegistryProxy', accounts => { GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Attach the implementation address', async () => { - // Storage - // __version -- index 11 - // __implementation -- index 12 - // __upgradeabilityOwner -- index 13 - - it('Should attach the MR implementation and version', async () => { - let bytesProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesProxy, { from: account_polymath }); - let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address); - assert.equal( - web3.utils - .toAscii(await readStorage(c.address, 11)) - .replace(/\u0000/g, '') - .replace(/\n/, ''), - '1.0.0' - ); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); }); - it('Deploy the essential smart contracts', async () => { - // STEP 4: Deploy the GeneralTransferManagerFactory + describe("Attach the implementation address", async() => { - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + // Storage + // __version -- index 11 + // __implementation -- index 12 + // __upgradeabilityOwner -- index 13 - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + it("Should attach the MR implementation and version", async() => { + let bytesProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, {from: account_polymath}); + let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); + assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address); + assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.0.0"); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + }); - // Register the Modules with the ModuleRegistry contract + it("Deploy the essential smart contracts", async() => { + // STEP 4: Deploy the GeneralTransferManagerFactory - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - // Step 3: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); - }); + // Register the Modules with the ModuleRegistry contract - it('Verify the initialize data', async () => { - assert.equal( - await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')), - account_polymath, - 'Should equal to right address' - ); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('polymathRegistry')), I_PolymathRegistry.address); - }); - }); - - describe('Feed some data in storage', async () => { - it('Register and verify the new module', async () => { - I_GeneralPermissionManagerfactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerfactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralPermissionManagerFactory contract was not deployed' - ); - - await I_MRProxied.registerModule(I_GeneralPermissionManagerfactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerfactory.address, true, { from: account_polymath }); - }); - }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - describe('Upgrade the imlplementation address', async () => { - it('Should upgrade the version and implementation address -- fail bad owner', async () => { - I_MockModuleRegistry = await MockModuleRegistry.new({ from: account_polymath }); - await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', I_MockModuleRegistry.address, { from: account_temp })); - }); - it('Should upgrade the version and implementation address -- Implementaion address should be a contract address', async () => { - await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', account_temp, { from: account_polymath })); - }); + // Step 3: Deploy the STFactory contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - it('Should upgrade the version and implementation address -- Implemenation address should not be 0x', async () => { - await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', '0x00000000000000000000000000000000000000', { from: account_polymath })); - }); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + }) - it('Should upgrade the version and implementation address -- Implemenation address should not be the same address', async () => { - await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.1.0', I_ModuleRegistry.address, { from: account_polymath })); - }); + it("Verify the initialize data", async() => { + assert.equal((await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("owner"))), account_polymath, "Should equal to right address"); + assert.equal((await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry"))), I_PolymathRegistry.address); + }); - it('Should upgrade the version and implementation address -- same version as previous is not allowed', async () => { - await catchRevert(I_ModuleRegistryProxy.upgradeTo('1.0.0', I_MockModuleRegistry.address, { from: account_polymath })); - }); + }) - it('Should upgrade the version and implementation address -- empty version string is not allowed', async () => { - await catchRevert(I_ModuleRegistryProxy.upgradeTo('', I_MockModuleRegistry.address, { from: account_polymath })); - }); + describe("Feed some data in storage", async() => { - it('Should upgrade the version and the implementation address successfully', async () => { - await I_ModuleRegistryProxy.upgradeTo('1.1.0', I_MockModuleRegistry.address, { from: account_polymath }); - let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal( - web3.utils - .toAscii(await readStorage(c.address, 11)) - .replace(/\u0000/g, '') - .replace(/\n/, ''), - '1.1.0', - 'Version mis-match' - ); - assert.equal(await readStorage(c.address, 12), I_MockModuleRegistry.address, 'Implemnted address is not matched'); - I_MRProxied = await MockModuleRegistry.at(I_ModuleRegistryProxy.address); - }); - }); + it("Register and verify the new module", async() => { - describe('Execute functionality of the implementation contract on the earlier storage', async () => { - it('Should get the previous data', async () => { - let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); - assert.equal(_data.length, 0, 'Should give the original length'); - }); + I_GeneralPermissionManagerfactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - it('Should alter the old storage', async () => { - await I_MRProxied.addMoreReputation(I_GeneralTransferManagerFactory.address, [account_polymath, account_temp], { - from: account_polymath - }); - let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); - assert.equal(_data.length, 2, 'Should give the updated length'); - }); - }); + assert.notEqual( + I_GeneralPermissionManagerfactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralPermissionManagerFactory contract was not deployed" + ); - describe('Transfer the ownership of the proxy contract', async () => { - it('Should change the ownership of the contract -- because of bad owner', async () => { - await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_temp })); - }); + await I_MRProxied.registerModule(I_GeneralPermissionManagerfactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerfactory.address, true, { from: account_polymath }); - it('Should change the ownership of the contract -- new address should not be 0x', async () => { - await catchRevert( - I_ModuleRegistryProxy.transferProxyOwnership('0x00000000000000000000000000000000000000', { from: account_polymath }) - ); - }); + }); - it('Should change the ownership of the contract', async () => { - await I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_polymath }); - let _currentOwner = await I_ModuleRegistryProxy.proxyOwner.call({ from: account_polymath_new }); - assert.equal(_currentOwner, account_polymath_new, 'Should equal to the new owner'); - }); + }) - it('Should change the implementation contract and version by the new owner', async () => { - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - await I_ModuleRegistryProxy.upgradeTo('1.2.0', I_ModuleRegistry.address, { from: account_polymath_new }); - let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal( - web3.utils - .toAscii(await readStorage(c.address, 11)) - .replace(/\u0000/g, '') - .replace(/\n/, ''), - '1.2.0', - 'Version mis-match' - ); - assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address, 'Implemnted address is not matched'); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + describe("Upgrade the imlplementation address", async() => { + + it("Should upgrade the version and implementation address -- fail bad owner", async() => { + + I_MockModuleRegistry = await MockModuleRegistry.new({from: account_polymath}); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_temp})); + }); + + it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { + + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { + + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { + + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_ModuleRegistry.address, {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { + + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.0.0", I_MockModuleRegistry.address, {from: account_polymath})); + }); + + it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { + + await catchRevert(I_ModuleRegistryProxy.upgradeTo("", I_MockModuleRegistry.address, {from: account_polymath})); + }); + + it("Should upgrade the version and the implementation address successfully", async() => { + await I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_polymath}); + let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); + assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.1.0", "Version mis-match"); + assert.equal(await readStorage(c.address, 12), I_MockModuleRegistry.address, "Implemnted address is not matched"); + I_MRProxied = await MockModuleRegistry.at(I_ModuleRegistryProxy.address); + }); }); - }); -}); + + describe("Execute functionality of the implementation contract on the earlier storage", async() => { + + it("Should get the previous data", async() => { + let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); + assert.equal(_data.length, 0, "Should give the original length"); + }); + + it("Should alter the old storage", async() => { + await I_MRProxied.addMoreReputation(I_GeneralTransferManagerFactory.address, [account_polymath, account_temp], {from: account_polymath}); + let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); + assert.equal(_data.length, 2, "Should give the updated length"); + }); + }) + + describe("Transfer the ownership of the proxy contract", async() => { + + it("Should change the ownership of the contract -- because of bad owner", async()=> { + + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); + }); + + it("Should change the ownership of the contract -- new address should not be 0x", async()=> { + + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); + }); + + it("Should change the ownership of the contract", async()=> { + await I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_polymath}); + let _currentOwner = await I_ModuleRegistryProxy.proxyOwner.call({from: account_polymath_new}); + assert.equal(_currentOwner, account_polymath_new, "Should equal to the new owner"); + }); + + it("Should change the implementation contract and version by the new owner", async() => { + I_ModuleRegistry = await ModuleRegistry.new({from: account_polymath}); + await I_ModuleRegistryProxy.upgradeTo("1.2.0", I_ModuleRegistry.address, {from: account_polymath_new}); + let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); + assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.2.0", "Version mis-match"); + assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address, "Implemnted address is not matched"); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + }); + }) + + +}) diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 4b8380424..1615a5ce1 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -4,7 +4,7 @@ import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; import { catchRevert } from './helpers/exceptions'; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol'); +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); @@ -22,182 +22,183 @@ const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); // Hardcoded development port +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port contract('TrackedRedemption', accounts => { - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = 'Transaction Should Fail!'; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_TrackedRedemptionFactory; - let I_GeneralPermissionManager; - let I_TrackedRedemption; - let I_GeneralTransferManager; - let I_ExchangeTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_STRProxied; - let I_STFactory; - let I_SecurityToken; - let I_PolyToken; - let I_MRProxied; - let I_PolymathRegistry; - - // SecurityToken Details - const name = 'Team'; - const symbol = 'sap'; - const tokenDetails = 'This is equity type of issuance'; - const decimals = 18; - const contact = 'team@polymath.network'; - let snapId; - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - const burnKey = 5; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei('250'); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async () => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall('1.0.0', I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_temp; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let I_GeneralTransferManagerFactory; + let I_TrackedRedemptionFactory; + let I_GeneralPermissionManager; + let I_TrackedRedemption; + let I_GeneralTransferManager; + let I_ExchangeTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_MRProxied; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + let snapId; + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const checkpointKey = 4; + const burnKey = 5; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralTransferManagerFactory contract was not deployed' - ); + // STEP 5: Deploy the GeneralDelegateManagerFactory - // STEP 5: Deploy the GeneralDelegateManagerFactory + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'GeneralDelegateManagerFactory contract was not deployed' - ); + // STEP 4: Deploy the TrackedRedemption + I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_TrackedRedemptionFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "TrackedRedemptionFactory contract was not deployed" + ); - // STEP 4: Deploy the TrackedRedemption - I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_TrackedRedemptionFactory.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'TrackedRedemptionFactory contract was not deployed' - ); - // Step 6: Deploy the STFactory contract + // Step 6: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - assert.notEqual(I_STFactory.address.valueOf(), '0x0000000000000000000000000000000000000000', 'STFactory contract was not deployed'); + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); - // Step 7: Deploy the SecurityTokenRegistry contract + // Step 7: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - '0x0000000000000000000000000000000000000000', - 'SecurityTokenRegistry contract was not deployed' - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall('1.0.0', I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress('PolyToken', I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('ModuleRegistry', I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('FeatureRegistry', I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress('SecurityTokenRegistry', I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); - // STEP 5: Register the Modules with the ModuleRegistry contract + // STEP 5: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the TrackedRedemptionFactory - await I_MRProxied.registerModule(I_TrackedRedemptionFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_TrackedRedemptionFactory.address, true, { from: account_polymath }); + // (C) : Register the TrackedRedemptionFactory + await I_MRProxied.registerModule(I_TrackedRedemptionFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_TrackedRedemptionFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -213,144 +214,161 @@ contract('TrackedRedemption', accounts => { TrackedRedemptionFactory: ${I_TrackedRedemptionFactory.address} ----------------------------------------------------------------------------- `); - }); - - describe('Generate the SecurityToken', async () => { - it('Should register the ticker before the generation of the security token', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); - it('Should generate the new security token with the same symbol as registered above', async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ''), 'GeneralTransferManager'); - }); - - it('Should intialize the auto attached modules', async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it('Should successfully attach the TrackedRedemption with the security token', async () => { - const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, '', 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._type.toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ''), - 'TrackedRedemption', - 'TrackedRedemption module was not added' - ); - I_TrackedRedemption = TrackedRedemption.at(tx.logs[2].args._module); + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + + }); + + it("Should successfully attach the TrackedRedemption with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, "", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._type.toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "TrackedRedemption", + "TrackedRedemption module was not added" + ); + I_TrackedRedemption = TrackedRedemption.at(tx.logs[2].args._module); + }); }); - }); - - describe('Make Redemptions', async () => { - it('Buy some tokens for account_investor1 (1 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Jump time - await increaseTime(5000); - // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + describe("Make Redemptions", async() => { + + it("Buy some tokens for account_investor1 (1 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + + it("Buy some tokens for account_investor2 (2 ETH)", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Redeem some tokens - fail insufficient allowance", async() => { + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); + + + await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1})); + }); + + it("Redeem some tokens", async() => { + await I_SecurityToken.approve(I_TrackedRedemption.address, web3.utils.toWei('1', 'ether'), {from: account_investor1}); + let tx = await I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1}); + console.log(JSON.stringify(tx.logs)); + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Mismatch address"); + assert.equal(tx.logs[0].args._value, web3.utils.toWei('1', 'ether'), "Wrong value"); + }); + + it("Get the init data", async() => { + let tx = await I_TrackedRedemption.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + }); + + it("Should get the listed permissions", async() => { + let tx = await I_TrackedRedemption.getPermissions.call(); + assert.equal(tx.length,0); + }); + + describe("Test cases for the TrackedRedemptionFactory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); + assert.equal(await I_TrackedRedemptionFactory.getType.call(), 5); + assert.equal(await I_TrackedRedemptionFactory.getVersion.call(), "1.0.0"); + assert.equal(web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()) + .replace(/\u0000/g, ''), + "TrackedRedemption", + "Wrong Module added"); + assert.equal(await I_TrackedRedemptionFactory.getDescription.call(), + "Track token redemptions", + "Wrong Module added"); + assert.equal(await I_TrackedRedemptionFactory.getTitle.call(), + "Tracked Redemption", + "Wrong Module added"); + assert.equal(await I_TrackedRedemptionFactory.getInstructions.call(), + "Allows an investor to redeem security tokens which are tracked by this module", + "Wrong Module added"); + let tags = await I_TrackedRedemptionFactory.getTags.call(); + assert.equal(tags.length, 2); + + }); + }); - assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei('1', 'ether')); }); - it('Buy some tokens for account_investor2 (2 ETH)', async () => { - // Add the Investor in to the whitelist - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - } - ); - - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), 'Failed in adding the investor in whitelist'); - - // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - - assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('2', 'ether')); - }); - - it('Redeem some tokens - fail insufficient allowance', async () => { - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); - - await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - }); - - it('Redeem some tokens', async () => { - await I_SecurityToken.approve(I_TrackedRedemption.address, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - let tx = await I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - console.log(JSON.stringify(tx.logs)); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), 'Mismatch address'); - assert.equal(tx.logs[0].args._value, web3.utils.toWei('1', 'ether'), 'Wrong value'); - }); - - it('Get the init data', async () => { - let tx = await I_TrackedRedemption.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''), 0); - }); - - it('Should get the listed permissions', async () => { - let tx = await I_TrackedRedemption.getPermissions.call(); - assert.equal(tx.length, 0); - }); - - describe('Test cases for the TrackedRedemptionFactory', async () => { - it('should get the exact details of the factory', async () => { - assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); - assert.equal(await I_TrackedRedemptionFactory.getType.call(), 5); - assert.equal(await I_TrackedRedemptionFactory.getVersion.call(), '1.0.0'); - assert.equal( - web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()).replace(/\u0000/g, ''), - 'TrackedRedemption', - 'Wrong Module added' - ); - assert.equal(await I_TrackedRedemptionFactory.getDescription.call(), 'Track token redemptions', 'Wrong Module added'); - assert.equal(await I_TrackedRedemptionFactory.getTitle.call(), 'Tracked Redemption', 'Wrong Module added'); - assert.equal( - await I_TrackedRedemptionFactory.getInstructions.call(), - 'Allows an investor to redeem security tokens which are tracked by this module', - 'Wrong Module added' - ); - let tags = await I_TrackedRedemptionFactory.getTags.call(); - assert.equal(tags.length, 2); - }); - }); - }); }); From 178add46b57b5b6f818c32a26656b1658374ab25 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 10:36:54 +0530 Subject: [PATCH 060/142] Capped STO test fix --- test/b_capped_sto.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 89ab08ecc..6a5040a50 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -462,12 +462,7 @@ contract('CappedSTO', accounts => { .toNumber(), 9000 ); - await catchRevert(web3.eth.sendTransaction({ - from: account_investor2, - to: I_CappedSTO_Array_ETH[0].address, - gas: 210000, - value: web3.utils.toWei('1', 'ether') - })); + await catchRevert(I_CappedSTO_Array_ETH[0].buyTokens(account_investor2, { value: web3.utils.toWei('100')})); }); it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { @@ -845,14 +840,22 @@ contract('CappedSTO', accounts => { .toNumber(), 45000 ); - - await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}); + await catchRevert(I_CappedSTO_Array_POLY[0].buyTokensWithPoly( + (1000 * Math.pow(10, 18)), + {from : account_investor1, gas: 6000000 } + ) + ); }); it("Should failed at the time of buying the tokens -- Because STO get expired", async() => { await increaseTime(duration.days(31)); // increased beyond the end time of the STO - - await catchRevert(I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1})); + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}) + await catchRevert(I_CappedSTO_Array_POLY[0].buyTokensWithPoly( + (1000 * Math.pow(10, 18)), + {from : account_investor1, gas: 6000000 } + ) + ); }); it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { From 0868f88db91efe19e995d62d568e2281c51767c7 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 10:48:43 +0530 Subject: [PATCH 061/142] erc20 dividend test cases fix --- test/e_erc20_dividends.js | 98 +++++++++++++-------------------------- 1 file changed, 33 insertions(+), 65 deletions(-) diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 59ef6d20d..2f490956a 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -169,8 +169,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment", async () => { await catchRevert( - I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }), - "tx -> failed because Token is not paid" + I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }) ); }); @@ -263,8 +262,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because allowance = 0" + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) ); }); @@ -273,8 +271,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() - duration.days(10); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because maturity > expiry" + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) ); }); @@ -282,8 +279,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because now > expiry" + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) ); }); @@ -291,8 +287,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}), - "tx -> failed because token address is 0x" + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) ); }); @@ -300,8 +295,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}), - "tx -> failed because amount < 0" + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}) ); }); @@ -322,8 +316,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}), - "tx -> failed because dividend index has maturity in future" + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}) ); }); @@ -331,15 +324,13 @@ contract('ERC20DividendCheckpoint', accounts => { // Increase time by 2 day await increaseTime(duration.days(2)); await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}), - "tx -> failed because msg.sender is not the owner" + I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}) ); }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}), - "tx -> failed because dividend index is greator than the dividend array length" + I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}) ); }); @@ -386,8 +377,7 @@ contract('ERC20DividendCheckpoint', accounts => { await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}), - "tx -> failed because dividend name is empty" + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}) ); }); @@ -403,8 +393,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry", async() => { await increaseTime(duration.days(12)); await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}), - "tx -> failed because dividend index has passed its expiry" + I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}) ); }); @@ -412,8 +401,7 @@ contract('ERC20DividendCheckpoint', accounts => { let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}), - "tx -> failed because dividend index has already been reclaimed" + I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}) ); }); @@ -468,8 +456,7 @@ contract('ERC20DividendCheckpoint', accounts => { while(limit--) addresses.push(limit); await catchRevert( - I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}), - "tx -> failed because exclude address more than limit" + I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}) ); }); @@ -484,8 +471,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("should investor 3 claims dividend - fail bad index", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}), - "tx -> failed because dividend index is not valid" + I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}) ); }); @@ -505,8 +491,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("should investor 3 claims dividend - fails already claimed", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}), - "tx -> failed because investor already claimed the dividend" + I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}) ); }); @@ -551,8 +536,7 @@ contract('ERC20DividendCheckpoint', accounts => { console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), - "tx -> failed because allowance is not provided" + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}) ); }); @@ -563,8 +547,7 @@ contract('ERC20DividendCheckpoint', accounts => { let expiry = latestTime() - duration.days(10); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), {from: token_owner}); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), - "tx -> failed because maturity > expiry" + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}) ); }); @@ -574,8 +557,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}), - "tx -> failed because now > expiry" + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}) ); }); @@ -583,8 +565,7 @@ contract('ERC20DividendCheckpoint', accounts => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}), - "tx -> failed because checkpoint id > current checkpoint" + I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}) ); }); @@ -594,15 +575,13 @@ contract('ERC20DividendCheckpoint', accounts => { it("Should not allow mismatching input lengths", async() => { await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}), - "tx -> failed because mismatching input lengths" + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}) ); }); it("Should not allow withholding greater than limit", async() => { await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**26)], {from: token_owner}), - "tx -> failed because withholding greater than limit" + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**26)], {from: token_owner}) ); await catchRevert( I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20*10**26), {from: token_owner}), @@ -622,8 +601,7 @@ contract('ERC20DividendCheckpoint', accounts => { while(limit--) addresses.push(limit); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, addresses, dividendName, {from: token_owner}), - "tx -> failed because too many address excluded" + I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, addresses, dividendName, {from: token_owner}) ); }); @@ -638,29 +616,25 @@ contract('ERC20DividendCheckpoint', accounts => { it("Should not allow excluded to pull Dividend Payment", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor1, gasPrice: 0}), - "tx -> failed because msg.sender is excluded" + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor1, gasPrice: 0}) ); }); it("Investor 2 claims dividend, issuer pushes investor 1 - fails not owner", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}), - "tx -> failed because not called by the owner" + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}) ); }); it("Investor 2 claims dividend, issuer pushes investor 1 - fails bad index", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}), - "tx -> failed because dividend index is not valid" + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}) ); }); it("should not calculate dividend for invalid index", async() => { await catchRevert( - I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1), - "tx -> failed because dividend index is not valid" + I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1) ); }); @@ -722,8 +696,7 @@ contract('ERC20DividendCheckpoint', accounts => { it("Should not allow reclaiming withholding tax with incorrect index", async() => { await catchRevert( - I_ERC20DividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), - "tx -> failed because dividend index is not valid" + I_ERC20DividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}) ); }); @@ -736,23 +709,20 @@ contract('ERC20DividendCheckpoint', accounts => { it("Issuer unable to reclaim dividend (expiry not passed)", async() => { await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner}), - "tx -> failed because expiry is in the future" + I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner}) ); }); it("Issuer is unable to reclaim invalid dividend", async() => { await increaseTime(11 * 24 * 60 * 60); await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}), - "tx -> failed because dividend index is not valid" + I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}) ); }); it("Investor 3 unable to pull dividend after expiry", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), - "tx -> failed because expiry is in the past" + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}) ); }); @@ -766,15 +736,13 @@ contract('ERC20DividendCheckpoint', accounts => { it("Issuer is unable to reclaim already reclaimed dividend", async() => { await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}), - "tx -> failed because dividend are already reclaimed" + I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}) ); }); it("Investor 3 unable to pull dividend after reclaiming", async() => { await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}), - "tx -> failed because expiry is in the past" + I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}) ); }); @@ -824,4 +792,4 @@ contract('ERC20DividendCheckpoint', accounts => { }); -}); +}); \ No newline at end of file From 7843f36eaadacec4fa04c63bc98df0cbedaff47d Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 10:49:12 +0530 Subject: [PATCH 062/142] Added prettier --- package.json | 4 +- test/a_poly_oracle.js | 290 ++- test/b_capped_sto.js | 814 +++---- test/c_checkpoints.js | 168 +- test/d_count_transfer_manager.js | 260 +-- test/e_erc20_dividends.js | 647 +++--- test/f_ether_dividends.js | 694 +++--- test/g_general_permission_manager.js | 351 +-- test/h_general_transfer_manager.js | 712 +++--- test/helpers/createInstances.js | 154 +- test/helpers/encodeCall.js | 17 +- test/helpers/exceptions.js | 88 +- test/helpers/latestTime.js | 7 +- test/helpers/signData.js | 30 +- test/helpers/testprivateKey.js | 6 +- test/helpers/time.js | 100 +- test/helpers/utils.js | 83 +- test/i_Issuance.js | 281 ++- test/j_manual_approval_transfer_manager.js | 516 +++-- test/k_module_registry.js | 491 ++-- test/l_percentage_transfer_manager.js | 309 +-- test/m_presale_sto.js | 339 ++- test/n_security_token_registry.js | 890 ++++---- test/o_security_token.js | 1289 +++++------ test/p_usd_tiered_sto.js | 2349 ++++++++++++++------ test/q_usd_tiered_sto_sim.js | 759 +++++-- test/r_concurrent_STO.js | 233 +- test/s_v130_to_v140_upgrade.js | 351 +-- test/t_security_token_registry_proxy.js | 259 ++- test/u_module_registry_proxy.js | 246 +- test/v_tracked_redemptions.js | 282 ++- 31 files changed, 7268 insertions(+), 5751 deletions(-) diff --git a/package.json b/package.json index 3e06d880f..1368f238d 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "flatten-oracles": "sol-merger './contracts/oracles/*.sol' ./flat/oracles", "flatten": "sol-merger './contracts/*.sol' ./flat", "ethereum-bridge": "node_modules/.bin/ethereum-bridge -H localhost:8545 -a 9 --dev", - "st20generator": "node demo/ST20Generator" + "st20generator": "node demo/ST20Generator", + "pretty": "prettier --write --print-width 140 --tab-width 4 \"**/*.js\"" }, "repository": { "type": "git", @@ -61,6 +62,7 @@ "ethereumjs-testrpc": "^6.0.3", "ethers": "^3.0.15", "openzeppelin-solidity": "1.10.0", + "prettier": "^1.14.3", "readline-sync": "^1.4.9", "shelljs": "^0.8.2", "solc": "^0.4.24", diff --git a/test/a_poly_oracle.js b/test/a_poly_oracle.js index da8268238..6363fe151 100644 --- a/test/a_poly_oracle.js +++ b/test/a_poly_oracle.js @@ -1,89 +1,92 @@ -const PolyOracle = artifacts.require('./MockPolyOracle.sol'); -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import {increaseTime} from './helpers/time'; -import { catchRevert } from './helpers/exceptions'; - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('PolyOracle', accounts=> { - -let I_PolyOracle; -let owner; -const URL = '[URL] json(https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?id=2496&convert=USD&CMC_PRO_API_KEY=${[decrypt] BBObnGOy63qVI3OR2+MX88dzSMVjQboiZc7Wluuh2ngkSgiX1csxWgbAFtu22jbrry42zwCS4IUmer1Wk+1o1XhF7hyspoGCkbufQqYwuUYwcA2slX6RbEDai7NgdkgNGWSwd6DcuN8jD5ZMTkX68rJKkplr}).data."2496".quote.USD.price'; -const alternateURL = "json(https://min-api.cryptocompare.com/data/price?fsym=POLY&tsyms=USD).USD"; -const SanityBounds = 20*10**16; -const GasLimit = 100000; -const TimeTolerance = 5*60; -const message = "Txn should fail"; -let latestPrice; -let requestIds = new Array(); - - before(async()=> { +const PolyOracle = artifacts.require("./MockPolyOracle.sol"); +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { increaseTime } from "./helpers/time"; +import { catchRevert } from "./helpers/exceptions"; + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("PolyOracle", accounts => { + let I_PolyOracle; + let owner; + const URL = + '[URL] json(https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?id=2496&convert=USD&CMC_PRO_API_KEY=${[decrypt] BBObnGOy63qVI3OR2+MX88dzSMVjQboiZc7Wluuh2ngkSgiX1csxWgbAFtu22jbrry42zwCS4IUmer1Wk+1o1XhF7hyspoGCkbufQqYwuUYwcA2slX6RbEDai7NgdkgNGWSwd6DcuN8jD5ZMTkX68rJKkplr}).data."2496".quote.USD.price'; + const alternateURL = "json(https://min-api.cryptocompare.com/data/price?fsym=POLY&tsyms=USD).USD"; + const SanityBounds = 20 * 10 ** 16; + const GasLimit = 100000; + const TimeTolerance = 5 * 60; + const message = "Txn should fail"; + let latestPrice; + let requestIds = new Array(); + + before(async () => { owner = accounts[0]; - I_PolyOracle = await PolyOracle.new({from : owner}); + I_PolyOracle = await PolyOracle.new({ from: owner }); }); - - describe("state variables checks", async() => { - - it("should set and check the api url", async() => { - await I_PolyOracle.setOracleURL(URL, {from: owner}); + describe("state variables checks", async () => { + it("should set and check the api url", async () => { + await I_PolyOracle.setOracleURL(URL, { from: owner }); let url = await I_PolyOracle.oracleURL.call(); assert.equal(URL, url); }); - it("should check the sanity bounds", async() => { + it("should check the sanity bounds", async () => { let sanityBounds = await I_PolyOracle.sanityBounds.call(); assert.equal(SanityBounds, sanityBounds); }); - it("should check the gas limits", async() => { + it("should check the gas limits", async () => { let gasLimit = await I_PolyOracle.gasLimit.call(); assert.equal(GasLimit, gasLimit); }); - it("should check the oraclize time tolerance", async() => { + it("should check the oraclize time tolerance", async () => { let timeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); assert.equal(TimeTolerance, timeTolerance); }); + }); - }) - - describe("Scheduling test cases", async() => { - - it("Should schedule the timing of the call - fails - non owner", async() => { - - let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] - await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: accounts[1], value: web3.utils.toWei("2")})); + describe("Scheduling test cases", async () => { + it("Should schedule the timing of the call - fails - non owner", async () => { + let timeScheduling = [ + latestTime() + duration.minutes(1), + latestTime() + duration.minutes(2), + latestTime() + duration.minutes(3) + ]; + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: accounts[1], value: web3.utils.toWei("2") })); }); - it("Should schedule the timing of the call - fails - no value", async() => { - - let timeScheduling = [latestTime()+duration.minutes(1), latestTime()+duration.minutes(2), latestTime()+duration.minutes(3)] - await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner})); - }) + it("Should schedule the timing of the call - fails - no value", async () => { + let timeScheduling = [ + latestTime() + duration.minutes(1), + latestTime() + duration.minutes(2), + latestTime() + duration.minutes(3) + ]; + await catchRevert(I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner })); + }); - it("Should schedule the timing of the call - single call", async() => { + it("Should schedule the timing of the call - single call", async () => { let blockNo = latestBlock(); - let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); + let tx = await I_PolyOracle.schedulePriceUpdatesFixed([], { from: owner, value: web3.utils.toWei("1") }); assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); // await increaseTime(50); const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); // const log = await logNewPriceWatcher; - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') + assert.equal(logNewPriceWatcher.event, "PriceUpdated", "PriceUpdated not emitted."); + assert.isNotNull(logNewPriceWatcher.args._price, "Price returned was null."); assert.equal(logNewPriceWatcher.args._oldPrice.toNumber(), 0); - console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') - + console.log( + "Success! Current price is: " + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + " USD/POLY" + ); }); - it("Should schedule the timing of the call - multiple calls", async() => { + it("Should schedule the timing of the call - multiple calls", async () => { let blockNo = latestBlock(); - let timeScheduling = [latestTime()+duration.seconds(10), latestTime()+duration.seconds(20)] - let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner, value:web3.utils.toWei("1.5")}); + let timeScheduling = [latestTime() + duration.seconds(10), latestTime() + duration.seconds(20)]; + let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner, value: web3.utils.toWei("1.5") }); let event_data = tx.logs; @@ -96,87 +99,81 @@ let requestIds = new Array(); // Wait for the callback to be invoked by oraclize and the event to be emitted const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); const log = await logNewPriceWatcher; - assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(log.args._price, 'Price returned was null.'); - console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY') + assert.equal(log.event, "PriceUpdated", "PriceUpdated not emitted."); + assert.isNotNull(log.args._price, "Price returned was null."); + console.log("Success! Current price is: " + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + " USD/POLY"); }); - it("Should schedule to call using iters - fails", async() => { - - await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, {from: accounts[6]})); - }) + it("Should schedule to call using iters - fails", async () => { + await catchRevert(I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 30, 2, { from: accounts[6] })); + }); - it("Should schedule to call using iters", async() => { + it("Should schedule to call using iters", async () => { let blockNo = latestBlock(); console.log(`Latest Block number of the local chain:${blockNo}`); - let tx = await I_PolyOracle.schedulePriceUpdatesRolling(latestTime()+10, 10, 2, {from: owner}); + let tx = await I_PolyOracle.schedulePriceUpdatesRolling(latestTime() + 10, 10, 2, { from: owner }); let event_data = tx.logs; for (var i = 0; i < event_data.length; i++) { let time = event_data[i].args._time; requestIds.push(event_data[i].args._queryId); console.log(` checking the time for the ${i} index and the scheduling time is ${time}`); - assert.isAtMost(time.toNumber(), latestTime() + ((i + 1) * 30)); + assert.isAtMost(time.toNumber(), latestTime() + (i + 1) * 30); } // Wait for the callback to be invoked by oraclize and the event to be emitted const logNewPriceWatcher = promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); const log = await logNewPriceWatcher; - assert.equal(log.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(log.args._price, 'Price returned was null.') - console.log('Success! Current price is: ' + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + assert.equal(log.event, "PriceUpdated", "PriceUpdated not emitted."); + assert.isNotNull(log.args._price, "Price returned was null."); + console.log("Success! Current price is: " + log.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + " USD/POLY"); latestPrice = log.args._price; }); - }) - - describe("Ownable functions", async() => { + }); - it("Should change the Poly USD price manually - fail - bad account", async() => { - - await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: accounts[5]})); + describe("Ownable functions", async () => { + it("Should change the Poly USD price manually - fail - bad account", async () => { + await catchRevert(I_PolyOracle.setPOLYUSD(latestPrice.add(1), { from: accounts[5] })); }); - it("Should change the Poly USD price manually", async() => { - await I_PolyOracle.setPOLYUSD(latestPrice.add(1), {from: owner}); + it("Should change the Poly USD price manually", async () => { + await I_PolyOracle.setPOLYUSD(latestPrice.add(1), { from: owner }); let price2 = await I_PolyOracle.getPriceAndTime.call(); assert.equal(price2[0].toNumber(), latestPrice.add(1).toNumber()); - }) + }); - it("Should freeze the Oracle manually", async() => { - - await catchRevert(I_PolyOracle.setFreezeOracle(true, {from: accounts[5]})); - }) + it("Should freeze the Oracle manually", async () => { + await catchRevert(I_PolyOracle.setFreezeOracle(true, { from: accounts[5] })); + }); - it("Should change the URL manually", async() => { + it("Should change the URL manually", async () => { let freeze_ = await I_PolyOracle.freezeOracle.call(); - await I_PolyOracle.setFreezeOracle(true, {from: owner}); + await I_PolyOracle.setFreezeOracle(true, { from: owner }); let freeze = await I_PolyOracle.freezeOracle.call(); assert.isFalse(freeze_); assert.isTrue(freeze); - await I_PolyOracle.setFreezeOracle(false, {from: owner}); - }) + await I_PolyOracle.setFreezeOracle(false, { from: owner }); + }); - it("Should change the sanity bounds manually - fails - bad owner", async() => { - - await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : accounts[6]})); - }) + it("Should change the sanity bounds manually - fails - bad owner", async () => { + await catchRevert(I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), { from: accounts[6] })); + }); - it("Should change the sanity bounds manually", async() => { + it("Should change the sanity bounds manually", async () => { console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); - await I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), {from : owner}); + await I_PolyOracle.setSanityBounds(new BigNumber(25).times(new BigNumber(10).pow(16)), { from: owner }); let sanityBounds = await I_PolyOracle.sanityBounds.call(); console.log(JSON.stringify(await I_PolyOracle.sanityBounds.call())); - assert.equal(sanityBounds.toNumber(), new BigNumber(25).times(new BigNumber(10).pow(16)).toNumber()) + assert.equal(sanityBounds.toNumber(), new BigNumber(25).times(new BigNumber(10).pow(16)).toNumber()); }); - it("Should change the gas price manually - fails - bad owner", async() => { - - await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : accounts[6]})); + it("Should change the gas price manually - fails - bad owner", async () => { + await catchRevert(I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)), { from: accounts[6] })); }); - it("Should change the gas price manually", async() => { - await I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)),{from : owner}); + it("Should change the gas price manually", async () => { + await I_PolyOracle.setGasPrice(new BigNumber(60).times(new BigNumber(10).pow(9)), { from: owner }); let blockNo = latestBlock(); - let timeScheduling = [latestTime()+duration.seconds(10), latestTime()+duration.seconds(20)]; - let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, {from: owner, value:web3.utils.toWei("2")}); + let timeScheduling = [latestTime() + duration.seconds(10), latestTime() + duration.seconds(20)]; + let tx = await I_PolyOracle.schedulePriceUpdatesFixed(timeScheduling, { from: owner, value: web3.utils.toWei("2") }); let event_data = tx.logs; @@ -188,96 +185,91 @@ let requestIds = new Array(); const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 2); - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') - console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + assert.equal(logNewPriceWatcher.event, "PriceUpdated", "PriceUpdated not emitted."); + assert.isNotNull(logNewPriceWatcher.args._price, "Price returned was null."); + console.log( + "Success! Current price is: " + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + " USD/POLY" + ); // assert.isTrue(false); - }); - it("Should change the gas limit manually - fails", async() => { - - await catchRevert(I_PolyOracle.setGasLimit(50000,{from : accounts[6]})); + it("Should change the gas limit manually - fails", async () => { + await catchRevert(I_PolyOracle.setGasLimit(50000, { from: accounts[6] })); }); - it("Should change the gas limit manually", async() => { - await I_PolyOracle.setGasLimit(50000,{from : owner}); + it("Should change the gas limit manually", async () => { + await I_PolyOracle.setGasLimit(50000, { from: owner }); let gasLimit = await I_PolyOracle.gasLimit.call(); - assert.equal(gasLimit.toNumber(),50000); - await I_PolyOracle.setGasLimit(100000,{from : owner}); + assert.equal(gasLimit.toNumber(), 50000); + await I_PolyOracle.setGasLimit(100000, { from: owner }); }); - it("Should blacklist some IDS manually - fails - wrong size", async() => { - + it("Should blacklist some IDS manually - fails - wrong size", async () => { let ignore = [true]; - await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds,ignore,{from : accounts[6]})); + await catchRevert(I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, { from: accounts[6] })); }); - it("Should blacklist some IDS manually", async() => { + it("Should blacklist some IDS manually", async () => { let ignore = [false, true]; console.log(requestIds); - await I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, {from : owner}); + await I_PolyOracle.setIgnoreRequestIds(requestIds, ignore, { from: owner }); // let ignoreRequestId0 = await I_PolyOracle.ignoreRequestIds.call(requestIds[1]); // assert.equal(ignoreRequestId0,true); // let ignoreRequestId1 = await I_PolyOracle.ignoreRequestIds.call(requestIds[2]); // assert.equal(ignoreRequestId1,false); - }); - it("Should change the oraclize time tolerance manually - fails", async() => { - - await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600,{from : accounts[6]})); - }) + it("Should change the oraclize time tolerance manually - fails", async () => { + await catchRevert(I_PolyOracle.setOraclizeTimeTolerance(3600, { from: accounts[6] })); + }); - it("Should change the oraclize time tolerance manually", async() => { - await I_PolyOracle.setOraclizeTimeTolerance(3600,{from : owner}); + it("Should change the oraclize time tolerance manually", async () => { + await I_PolyOracle.setOraclizeTimeTolerance(3600, { from: owner }); let oraclizeTimeTolerance = await I_PolyOracle.oraclizeTimeTolerance.call(); - assert.equal(oraclizeTimeTolerance.toNumber(),3600); + assert.equal(oraclizeTimeTolerance.toNumber(), 3600); }); - it("should change the api URL manually", async() => { - - await catchRevert(I_PolyOracle.setOracleURL(alternateURL, {from: accounts[6]})); - }) + it("should change the api URL manually", async () => { + await catchRevert(I_PolyOracle.setOracleURL(alternateURL, { from: accounts[6] })); + }); - it("should change the api URL manually", async() => { - await I_PolyOracle.setOracleURL(alternateURL, {from: owner}); - await I_PolyOracle.setOracleQueryType("URL", {from: owner}); + it("should change the api URL manually", async () => { + await I_PolyOracle.setOracleURL(alternateURL, { from: owner }); + await I_PolyOracle.setOracleQueryType("URL", { from: owner }); let url = await I_PolyOracle.oracleURL.call(); assert.equal(alternateURL, url); }); - it("Should schedule the timing of the call - after changes", async() => { + it("Should schedule the timing of the call - after changes", async () => { let blockNo = latestBlock(); - let tx = await I_PolyOracle.schedulePriceUpdatesFixed([],{from: owner, value:web3.utils.toWei("1")}); + let tx = await I_PolyOracle.schedulePriceUpdatesFixed([], { from: owner, value: web3.utils.toWei("1") }); assert.isAtMost(tx.logs[0].args._time.toNumber(), latestTime()); const logNewPriceWatcher = await promisifyLogWatch(I_PolyOracle.PriceUpdated({ fromBlock: blockNo }), 1); - assert.equal(logNewPriceWatcher.event, 'PriceUpdated', 'PriceUpdated not emitted.') - assert.isNotNull(logNewPriceWatcher.args._price, 'Price returned was null.') - console.log('Success! Current price is: ' + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + ' USD/POLY'); + assert.equal(logNewPriceWatcher.event, "PriceUpdated", "PriceUpdated not emitted."); + assert.isNotNull(logNewPriceWatcher.args._price, "Price returned was null."); + console.log( + "Success! Current price is: " + logNewPriceWatcher.args._price.dividedBy(new BigNumber(10).pow(18)).toNumber() + " USD/POLY" + ); // assert.isTrue(false); }); + }); - }) - - describe("Get Functions call", async() => { - it("Should get the currency address", async() => { + describe("Get Functions call", async () => { + it("Should get the currency address", async () => { let polyTokenAddress = await I_PolyOracle.getCurrencyAddress.call(); - assert.equal(polyTokenAddress, ("0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC").toLowerCase()); + assert.equal(polyTokenAddress, "0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC".toLowerCase()); }); - it("Should get the currency symbol", async() => { + it("Should get the currency symbol", async () => { let currency = await I_PolyOracle.getCurrencySymbol.call(); - assert.equal(web3.utils.toAscii(currency).replace(/\u0000/g, ''), "POLY"); + assert.equal(web3.utils.toAscii(currency).replace(/\u0000/g, ""), "POLY"); }); - it("Should get the currency denomination", async() => { + it("Should get the currency denomination", async () => { let denomination = await I_PolyOracle.getCurrencyDenominated.call(); - assert.equal(web3.utils.toAscii(denomination).replace(/\u0000/g, ''), "USD"); - }) - - }) - -}) + assert.equal(web3.utils.toAscii(denomination).replace(/\u0000/g, ""), "USD"); + }); + }); +}); diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 6a5040a50..6a788086b 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -1,25 +1,25 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeModuleCall } from './helpers/encodeCall'; -import { setUpPolymathNetwork } from './helpers/createInstances'; -import { catchRevert } from './helpers/exceptions'; - -const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); -const CappedSTO = artifacts.require('./CappedSTO.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeModuleCall } from "./helpers/encodeCall"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { catchRevert } from "./helpers/exceptions"; + +const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); +const CappedSTO = artifacts.require("./CappedSTO.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port let ETH = 0; let POLY = 1; let DAI = 2; -contract('CappedSTO', accounts => { +contract("CappedSTO", accounts => { // Accounts Variable declaration let account_polymath; let account_investor1; @@ -98,28 +98,41 @@ contract('CappedSTO', accounts => { const P_cap = web3.utils.toWei("50000"); const P_fundRaiseType = 1; const P_rate = 5; - const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); + const cappedSTOSetupCost = web3.utils.toWei("20000", "ether"); const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; account_investor1 = accounts[4]; account_investor2 = accounts[3]; - account_investor3 = accounts[5] + account_investor3 = accounts[5]; account_fundsReceiver = accounts[2]; token_owner = account_issuer; let instances = await setUpPolymathNetwork(account_polymath, token_owner); - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 5: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -137,7 +150,6 @@ contract('CappedSTO', accounts => { "CappedSTOFactory contract was not deployed" ); - // STEP 7: Register the Modules with the ModuleRegistry contract // (B) : Register the GeneralDelegateManagerFactory @@ -148,7 +160,6 @@ contract('CappedSTO', accounts => { await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- @@ -168,17 +179,16 @@ contract('CappedSTO', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol); }); it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); @@ -187,22 +197,22 @@ contract('CappedSTO', accounts => { I_SecurityToken_ETH = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken_ETH.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken_ETH.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken_ETH.getModulesByType(transferManagerKey))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + let moduleData = (await I_SecurityToken_ETH.getModulesByType(transferManagerKey))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - it("Should mint the tokens before attaching the STO", async() => { - - await catchRevert(I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), {from: token_owner})); + it("Should mint the tokens before attaching the STO", async () => { + await catchRevert( + I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), { from: token_owner }) + ); }); it("Should fail to launch the STO due to security token doesn't have the sufficient POLY", async () => { @@ -211,69 +221,66 @@ contract('CappedSTO', accounts => { await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to launch the STO due to rate is 0", async () => { let startTime = latestTime() + duration.days(1); let endTime = startTime + duration.days(30); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner}); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner }); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, 0, [E_fundRaiseType], account_fundsReceiver]); - + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to launch the STO due to startTime > endTime", async () => { - let bytesSTO = encodeModuleCall(STOParameters, [ Math.floor(Date.now()/1000 + 100000), Math.floor(Date.now()/1000 + 1000), cap, rate, [E_fundRaiseType], account_fundsReceiver]); - + let bytesSTO = encodeModuleCall(STOParameters, [ + Math.floor(Date.now() / 1000 + 100000), + Math.floor(Date.now() / 1000 + 1000), + cap, + rate, + [E_fundRaiseType], + account_fundsReceiver + ]); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should fail to launch the STO due to cap is of 0 securityToken", async () => { let startTime = latestTime() + duration.days(1); let endTime = startTime + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [ startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); - + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, 0, rate, [E_fundRaiseType], account_fundsReceiver]); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); it("Should successfully attach the STO module to the security token", async () => { startTime_ETH1 = latestTime() + duration.days(1); endTime_ETH1 = startTime_ETH1 + duration.days(30); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + let bytesSTO = encodeModuleCall(STOParameters, [ + startTime_ETH1, + endTime_ETH1, + cap, + rate, + [E_fundRaiseType], + account_fundsReceiver + ]); const tx = await I_SecurityToken_ETH.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.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); }); }); describe("verify the data of STO", async () => { - - it("Should verify the configuration of the STO", async() => { - assert.equal( - await I_CappedSTO_Array_ETH[0].startTime.call(), - startTime_ETH1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[0].endTime.call(), - endTime_ETH1, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_ETH[0].cap.call()).toNumber(), - cap, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[0].rate.call(), - rate, - "STO Configuration doesn't set as expected" - ); + it("Should verify the configuration of the STO", async () => { + assert.equal(await I_CappedSTO_Array_ETH[0].startTime.call(), startTime_ETH1, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[0].endTime.call(), endTime_ETH1, "STO Configuration doesn't set as expected"); + assert.equal((await I_CappedSTO_Array_ETH[0].cap.call()).toNumber(), cap, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[0].rate.call(), rate, "STO Configuration doesn't set as expected"); assert.equal( await I_CappedSTO_Array_ETH[0].fundRaiseTypes.call(E_fundRaiseType), true, @@ -282,45 +289,48 @@ contract('CappedSTO', accounts => { }); }); - describe("Buy tokens", async() => { - + describe("Buy tokens", async () => { it("Should buy the tokens -- failed due to startTime is greater than Current time", async () => { - - await catchRevert(web3.eth.sendTransaction({ + await catchRevert( + web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('1', 'ether') - })); + value: web3.utils.toWei("1", "ether") + }) + ); }); it("Should buy the tokens -- failed due to invested amount is zero", async () => { - - await catchRevert(web3.eth.sendTransaction({ + await catchRevert( + web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0', 'ether') - })); + value: web3.utils.toWei("0", "ether") + }) + ); }); it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - - await catchRevert(web3.eth.sendTransaction({ + await catchRevert( + web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('1', 'ether') - })); + value: web3.utils.toWei("1", "ether") + }) + ); }); it("Should buy the tokens -- Failed due to wrong granularity", async () => { - - await catchRevert(web3.eth.sendTransaction({ + await catchRevert( + web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0.1111', 'ether') - })); + value: web3.utils.toWei("0.1111", "ether") + }) + ); }); - it("Should Buy the tokens", async() => { + it("Should Buy the tokens", async () => { blockNo = latestBlock(); fromTime = latestTime(); toTime = latestTime() + duration.days(15); @@ -332,16 +342,10 @@ contract('CappedSTO', accounts => { balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); // Add the Investor in to the whitelist - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 500000 + }); assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); @@ -352,80 +356,64 @@ contract('CappedSTO', accounts => { from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); + value: web3.utils.toWei("1", "ether") + }); - assert.equal( - (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); + assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 1); - assert.equal( - (await I_SecurityToken_ETH.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); + assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); }); - it("Verification of the event Token Purchase", async() => { - const log = await promisifyLogWatch(I_CappedSTO_Array_ETH[0].TokenPurchase({from: blockNo}), 1); + it("Verification of the event Token Purchase", async () => { + const log = await promisifyLogWatch(I_CappedSTO_Array_ETH[0].TokenPurchase({ from: blockNo }), 1); assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); - assert.equal( - (log.args.amount) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000, - "Wrong No. token get dilivered" - ); + assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000, "Wrong No. token get dilivered"); }); - it("Should pause the STO -- Failed due to wrong msg.sender", async()=> { - - await catchRevert(I_CappedSTO_Array_ETH[0].pause({from: account_investor1})); + it("Should pause the STO -- Failed due to wrong msg.sender", async () => { + await catchRevert(I_CappedSTO_Array_ETH[0].pause({ from: account_investor1 })); }); - it("Should pause the STO", async()=> { + it("Should pause the STO", async () => { pauseTime = latestTime(); - let tx = await I_CappedSTO_Array_ETH[0].pause({from: account_issuer}); + let tx = await I_CappedSTO_Array_ETH[0].pause({ from: account_issuer }); assert.isTrue(await I_CappedSTO_Array_ETH[0].paused.call()); }); - it("Should fail to buy the tokens after pausing the STO", async() => { - - await catchRevert(web3.eth.sendTransaction({ + it("Should fail to buy the tokens after pausing the STO", async () => { + await catchRevert( + web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); + value: web3.utils.toWei("1", "ether") + }) + ); }); - it("Should unpause the STO -- Failed due to wrong msg.sender", async()=> { - - await catchRevert(I_CappedSTO_Array_ETH[0].unpause({from: account_investor1})); + it("Should unpause the STO -- Failed due to wrong msg.sender", async () => { + await catchRevert(I_CappedSTO_Array_ETH[0].unpause({ from: account_investor1 })); }); - it("Should unpause the STO", async()=> { - let tx = await I_CappedSTO_Array_ETH[0].unpause({from: account_issuer}); + it("Should unpause the STO", async () => { + let tx = await I_CappedSTO_Array_ETH[0].unpause({ from: account_issuer }); assert.isFalse(await I_CappedSTO_Array_ETH[0].paused.call()); }); it("Should buy the tokens -- Failed due to wrong granularity", async () => { - - await catchRevert(web3.eth.sendTransaction({ + await catchRevert( + web3.eth.sendTransaction({ from: account_investor1, to: I_CappedSTO_Array_ETH[0].address, - value: web3.utils.toWei('0.1111', 'ether') - })); + value: web3.utils.toWei("0.1111", "ether") + }) + ); }); - it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async() => { + it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async () => { let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor2, fromTime, @@ -435,40 +423,33 @@ contract('CappedSTO', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - // Fallback transaction - await web3.eth.sendTransaction({ + // Fallback transaction + await web3.eth.sendTransaction({ from: account_investor2, to: I_CappedSTO_Array_ETH[0].address, gas: 2100000, - value: web3.utils.toWei('9', 'ether') - }); - - assert.equal( - (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 10 - ); + value: web3.utils.toWei("9", "ether") + }); + + assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10); assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 2); - assert.equal( - (await I_SecurityToken_ETH.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 9000 - ); - await catchRevert(I_CappedSTO_Array_ETH[0].buyTokens(account_investor2, { value: web3.utils.toWei('100')})); + assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 9000); + await catchRevert(I_CappedSTO_Array_ETH[0].buyTokens(account_investor2, { value: web3.utils.toWei("100") })); }); - it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { + it("Should fundRaised value equal to the raised value in the funds receiver wallet", async () => { const newBalance = await web3.eth.getBalance(account_fundsReceiver); //console.log("WWWW",newBalance,await I_CappedSTO.fundsRaised.call(),balanceOfReceiver); - let op = (BigNumber(newBalance).minus(balanceOfReceiver)).toNumber(); + let op = BigNumber(newBalance) + .minus(balanceOfReceiver) + .toNumber(); assert.equal( (await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).toNumber(), op, @@ -476,79 +457,81 @@ contract('CappedSTO', accounts => { ); }); - it("Should get the raised amount of ether", async() => { - assert.equal(await I_CappedSTO_Array_ETH[0].getRaised.call(ETH), web3.utils.toWei('10','ether')); + it("Should get the raised amount of ether", async () => { + assert.equal(await I_CappedSTO_Array_ETH[0].getRaised.call(ETH), web3.utils.toWei("10", "ether")); }); - it("Should get the raised amount of poly", async() => { - assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('0','ether')); - }); - + it("Should get the raised amount of poly", async () => { + assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei("0", "ether")); + }); }); - describe("Reclaim poly sent to STO by mistake", async() => { - - it("Should fail to reclaim POLY because token contract address is 0 address", async() => { - let value = web3.utils.toWei('100','ether'); + describe("Reclaim poly sent to STO by mistake", async () => { + it("Should fail to reclaim POLY because token contract address is 0 address", async () => { + let value = web3.utils.toWei("100", "ether"); await I_PolyToken.getTokens(value, account_investor1); await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); - - await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); + await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20("0x0000000000000000000000000000000000000000", { from: token_owner })); }); - it("Should successfully reclaim POLY", async() => { + it("Should successfully reclaim POLY", async () => { let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); let initContractBalance = await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address); - let value = web3.utils.toWei('100','ether'); + let value = web3.utils.toWei("100", "ether"); await I_PolyToken.getTokens(value, account_investor1); await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); await I_CappedSTO_Array_ETH[0].reclaimERC20(I_PolyToken.address, { from: token_owner }); - assert.equal((await I_PolyToken.balanceOf(account_investor3)).toNumber(), initInvestorBalance.toNumber(), "tokens are not transfered out from investor account"); - assert.equal((await I_PolyToken.balanceOf(token_owner)).toNumber(), initOwnerBalance.add(value).add(initContractBalance).toNumber(), "tokens are not added to the owner account"); - assert.equal((await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address)).toNumber(), 0, "tokens are not trandfered out from STO contract"); + assert.equal( + (await I_PolyToken.balanceOf(account_investor3)).toNumber(), + initInvestorBalance.toNumber(), + "tokens are not transfered out from investor account" + ); + assert.equal( + (await I_PolyToken.balanceOf(token_owner)).toNumber(), + initOwnerBalance + .add(value) + .add(initContractBalance) + .toNumber(), + "tokens are not added to the owner account" + ); + assert.equal( + (await I_PolyToken.balanceOf(I_CappedSTO_Array_ETH[0].address)).toNumber(), + 0, + "tokens are not trandfered out from STO contract" + ); }); }); - describe("Attach second ETH STO module", async() => { - + describe("Attach second ETH STO module", async () => { it("Should successfully attach the second STO module to the security token", async () => { startTime_ETH2 = latestTime() + duration.days(1); endTime_ETH2 = startTime_ETH2 + duration.days(30); await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner}); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_ETH2, endTime_ETH2, cap, rate, [E_fundRaiseType], account_fundsReceiver]); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost, { from: token_owner }); + let bytesSTO = encodeModuleCall(STOParameters, [ + startTime_ETH2, + endTime_ETH2, + cap, + rate, + [E_fundRaiseType], + account_fundsReceiver + ]); const tx = await I_SecurityToken_ETH.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.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); }); - it("Should verify the configuration of the STO", async() => { - assert.equal( - await I_CappedSTO_Array_ETH[1].startTime.call(), - startTime_ETH2, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[1].endTime.call(), - endTime_ETH2, - "STO Configuration doesn't set as expected" - ); - assert.equal( - (await I_CappedSTO_Array_ETH[1].cap.call()).toNumber(), - cap, - "STO Configuration doesn't set as expected" - ); - assert.equal( - await I_CappedSTO_Array_ETH[1].rate.call(), - rate, - "STO Configuration doesn't set as expected" - ); + it("Should verify the configuration of the STO", async () => { + assert.equal(await I_CappedSTO_Array_ETH[1].startTime.call(), startTime_ETH2, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[1].endTime.call(), endTime_ETH2, "STO Configuration doesn't set as expected"); + assert.equal((await I_CappedSTO_Array_ETH[1].cap.call()).toNumber(), cap, "STO Configuration doesn't set as expected"); + assert.equal(await I_CappedSTO_Array_ETH[1].rate.call(), rate, "STO Configuration doesn't set as expected"); assert.equal( await I_CappedSTO_Array_ETH[1].fundRaiseTypes.call(E_fundRaiseType), true, @@ -556,20 +539,13 @@ contract('CappedSTO', accounts => { ); }); - it("Should successfully whitelist investor 3", async() => { - + it("Should successfully whitelist investor 3", async () => { balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 500000 + }); assert.equal(tx.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); @@ -577,71 +553,59 @@ contract('CappedSTO', accounts => { await increaseTime(duration.days(2)); }); - it("Should invest in second STO - fails due to incorrect beneficiary", async() => { - + it("Should invest in second STO - fails due to incorrect beneficiary", async () => { // Buying on behalf of another user should fail - - await catchRevert(I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') })); + await catchRevert( + I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from: account_issuer, value: web3.utils.toWei("1", "ether") }) + ); }); - it("Should allow non-matching beneficiary", async() => { - await I_CappedSTO_Array_ETH[1].changeAllowBeneficialInvestments(true, {from: account_issuer}); + it("Should allow non-matching beneficiary", async () => { + await I_CappedSTO_Array_ETH[1].changeAllowBeneficialInvestments(true, { from: account_issuer }); let allow = await I_CappedSTO_Array_ETH[1].allowBeneficialInvestments(); assert.equal(allow, true, "allowBeneficialInvestments should be true"); }); - it("Should invest in second STO", async() => { - - await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from : account_issuer, value: web3.utils.toWei('1', 'ether') }); + it("Should invest in second STO", async () => { + await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from: account_issuer, value: web3.utils.toWei("1", "ether") }); - assert.equal( - (await I_CappedSTO_Array_ETH[1].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); + assert.equal((await I_CappedSTO_Array_ETH[1].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); assert.equal(await I_CappedSTO_Array_ETH[1].investorCount.call(), 1); - assert.equal( - (await I_SecurityToken_ETH.balanceOf(account_investor3)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); + assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor3)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); }); }); - describe("Test cases for reaching limit number of STO modules", async() => { - + describe("Test cases for reaching limit number of STO modules", async () => { it("Should successfully attach 10 STO modules", async () => { const MAX_MODULES = 10; let startTime = latestTime() + duration.days(1); let endTime = startTime + duration.days(30); - await I_PolyToken.getTokens(cappedSTOSetupCost*19, token_owner); - await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost*19, { from: token_owner}); + await I_PolyToken.getTokens(cappedSTOSetupCost * 19, token_owner); + await I_PolyToken.transfer(I_SecurityToken_ETH.address, cappedSTOSetupCost * 19, { from: token_owner }); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], account_fundsReceiver]); for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", `Wrong STO module added at index ${STOIndex}`); I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); } - }); it("Should successfully invest in all STO modules attached", async () => { const MAX_MODULES = 10; await increaseTime(duration.days(2)); for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { - await I_CappedSTO_Array_ETH[STOIndex].buyTokens(account_investor3, { from : account_investor3, value: web3.utils.toWei('1', 'ether') }); + await I_CappedSTO_Array_ETH[STOIndex].buyTokens(account_investor3, { + from: account_investor3, + value: web3.utils.toWei("1", "ether") + }); assert.equal( - (await I_CappedSTO_Array_ETH[STOIndex].getRaised.call(ETH)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_CappedSTO_Array_ETH[STOIndex].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1 ); assert.equal(await I_CappedSTO_Array_ETH[STOIndex].investorCount.call(), 1); @@ -649,19 +613,17 @@ contract('CappedSTO', accounts => { }); }); - describe("Test Cases for an STO of fundraise type POLY", async() => { - - describe("Launch a new SecurityToken", async() => { - + describe("Test Cases for an STO of fundraise type POLY", async () => { + describe("Launch a new SecurityToken", async () => { it("POLY: Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, P_symbol, P_name, { from : token_owner }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, P_symbol, P_name, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, P_symbol); }); it("POLY: Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, { from: token_owner }); @@ -670,39 +632,44 @@ contract('CappedSTO', accounts => { I_SecurityToken_POLY = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken_POLY.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken_POLY.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager"); }); it("POLY: Should intialize the auto attached modules", async () => { let moduleData = (await I_SecurityToken_POLY.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); + }); - it("POLY: Should successfully attach the STO module to the security token", async () => { + it("POLY: Should successfully attach the STO module to the security token", async () => { startTime_POLY1 = latestTime() + duration.days(2); endTime_POLY1 = startTime_POLY1 + duration.days(30); await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner}); + await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY1, endTime_POLY1, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); + let bytesSTO = encodeModuleCall(STOParameters, [ + startTime_POLY1, + endTime_POLY1, + P_cap, + P_rate, + [P_fundRaiseType], + account_fundsReceiver + ]); const tx = await I_SecurityToken_POLY.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.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); }); - }); describe("verify the data of STO", async () => { - - it("Should verify the configuration of the STO", async() => { + it("Should verify the configuration of the STO", async () => { assert.equal( (await I_CappedSTO_Array_POLY[0].startTime.call()).toNumber(), startTime_POLY1, @@ -718,11 +685,7 @@ contract('CappedSTO', accounts => { BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), "STO Configuration doesn't set as expected" ); - assert.equal( - await I_CappedSTO_Array_POLY[0].rate.call(), - P_rate, - "STO Configuration doesn't set as expected" - ); + assert.equal(await I_CappedSTO_Array_POLY[0].rate.call(), P_rate, "STO Configuration doesn't set as expected"); assert.equal( await I_CappedSTO_Array_POLY[0].fundRaiseTypes.call(P_fundRaiseType), true, @@ -731,77 +694,52 @@ contract('CappedSTO', accounts => { }); }); - describe("Buy tokens", async() => { - - it("Should Buy the tokens", async() => { - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_investor1); + describe("Buy tokens", async () => { + it("Should Buy the tokens", async () => { + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_investor1); blockNo = latestBlock(); assert.equal( - (await I_PolyToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_PolyToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10000, "Tokens are not transfered properly" ); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - P_fromTime, - P_toTime, - P_expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, P_fromTime, P_toTime, P_expiryTime, true, { + from: account_issuer, + gas: 500000 + }); assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); // Jump time await increaseTime(duration.days(17)); - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}); + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 }); // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (1000 * Math.pow(10, 18)), - { - from : account_investor1, - gas: 6000000 - } - ); + await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { + from: account_investor1, + gas: 6000000 + }); - assert.equal( - (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); + assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 1); assert.equal( - (await I_SecurityToken_POLY.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_SecurityToken_POLY.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 5000 ); }); - it("Verification of the event Token Purchase", async() => { - const log = await promisifyLogWatch(I_CappedSTO_Array_POLY[0].TokenPurchase({from: blockNo}), 1); + it("Verification of the event Token Purchase", async () => { + const log = await promisifyLogWatch(I_CappedSTO_Array_POLY[0].TokenPurchase({ from: blockNo }), 1); assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); - assert.equal( - (log.args.amount) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 5000, - "Wrong No. token get dilivered" - ); + assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 5000, "Wrong No. token get dilivered"); }); - it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async() => { + it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async () => { let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor2, P_fromTime, @@ -811,54 +749,41 @@ contract('CappedSTO', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_investor2); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_investor2); - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (9000 * Math.pow(10, 18)), { from: account_investor2}); + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 9000 * Math.pow(10, 18), { from: account_investor2 }); // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (9000 * Math.pow(10, 18)), - {from : account_investor2, gas: 6000000 } - ); + await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(9000 * Math.pow(10, 18), { from: account_investor2, gas: 6000000 }); - assert.equal( - (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 10000 - ); + assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10000); assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); assert.equal( - (await I_SecurityToken_POLY.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_SecurityToken_POLY.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 45000 ); - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}); - await catchRevert(I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (1000 * Math.pow(10, 18)), - {from : account_investor1, gas: 6000000 } - ) + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 }); + await catchRevert( + I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { from: account_investor1, gas: 6000000 }) ); }); - it("Should failed at the time of buying the tokens -- Because STO get expired", async() => { + it("Should failed at the time of buying the tokens -- Because STO get expired", async () => { await increaseTime(duration.days(31)); // increased beyond the end time of the STO - await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, (1000 * Math.pow(10, 18)), { from: account_investor1}) - await catchRevert(I_CappedSTO_Array_POLY[0].buyTokensWithPoly( - (1000 * Math.pow(10, 18)), - {from : account_investor1, gas: 6000000 } - ) + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 }); + await catchRevert( + I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { from: account_investor1, gas: 6000000 }) ); }); - it("Should fundRaised value equal to the raised value in the funds receiver wallet", async() => { + it("Should fundRaised value equal to the raised value in the funds receiver wallet", async () => { const balanceRaised = await I_PolyToken.balanceOf.call(account_fundsReceiver); assert.equal( (await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), @@ -866,138 +791,127 @@ contract('CappedSTO', accounts => { "Somewhere raised money get stolen or sent to wrong wallet" ); }); + }); - }); - - describe("Test cases for the CappedSTOFactory", async() => { - it("should get the exact details of the factory", async() => { + describe("Test cases for the CappedSTOFactory", async () => { + it("should get the exact details of the factory", async () => { assert.equal((await I_CappedSTOFactory.setupCost.call()).toNumber(), cappedSTOSetupCost); - assert.equal((await I_CappedSTOFactory.getTypes.call())[0],3); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), - "CappedSTO", - "Wrong Module added"); - assert.equal(await I_CappedSTOFactory.getDescription.call(), - "Use to collects the funds and once the cap is reached then investment will be no longer entertained", - "Wrong Module added"); - assert.equal(await I_CappedSTOFactory.getTitle.call(), - "Capped STO", - "Wrong Module added"); - assert.equal(await I_CappedSTOFactory.getInstructions.call(), - "Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)", - "Wrong Module added"); + assert.equal((await I_CappedSTOFactory.getTypes.call())[0], 3); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), "CappedSTO", "Wrong Module added"); + assert.equal( + await I_CappedSTOFactory.getDescription.call(), + "Use to collects the funds and once the cap is reached then investment will be no longer entertained", + "Wrong Module added" + ); + assert.equal(await I_CappedSTOFactory.getTitle.call(), "Capped STO", "Wrong Module added"); + assert.equal( + await I_CappedSTOFactory.getInstructions.call(), + "Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)", + "Wrong Module added" + ); let tags = await I_CappedSTOFactory.getTags.call(); - assert.equal(web3.utils.hexToString(tags[0]),"Capped"); - + assert.equal(web3.utils.hexToString(tags[0]), "Capped"); }); - it("Should fail to change the title -- bad owner", async() => { - - await catchRevert(I_CappedSTOFactory.changeTitle("STO Capped", {from:account_investor1})); + it("Should fail to change the title -- bad owner", async () => { + await catchRevert(I_CappedSTOFactory.changeTitle("STO Capped", { from: account_investor1 })); }); - it("Should fail to change the title -- zero length", async() => { - - await catchRevert(I_CappedSTOFactory.changeTitle("", {from: token_owner})); + it("Should fail to change the title -- zero length", async () => { + await catchRevert(I_CappedSTOFactory.changeTitle("", { from: token_owner })); }); - it("Should successfully change the title", async() => { - await I_CappedSTOFactory.changeTitle("STO Capped", {from: token_owner}); - assert.equal(await I_CappedSTOFactory.getTitle.call(), - "STO Capped", - "Title doesn't get changed"); + it("Should successfully change the title", async () => { + await I_CappedSTOFactory.changeTitle("STO Capped", { from: token_owner }); + assert.equal(await I_CappedSTOFactory.getTitle.call(), "STO Capped", "Title doesn't get changed"); }); - it("Should fail to change the description -- bad owner", async() => { - - await catchRevert(I_CappedSTOFactory.changeDescription("It is only a STO", {from:account_investor1})); + it("Should fail to change the description -- bad owner", async () => { + await catchRevert(I_CappedSTOFactory.changeDescription("It is only a STO", { from: account_investor1 })); }); - it("Should fail to change the description -- zero length", async() => { - - await catchRevert(I_CappedSTOFactory.changeDescription("", {from: token_owner})); + it("Should fail to change the description -- zero length", async () => { + await catchRevert(I_CappedSTOFactory.changeDescription("", { from: token_owner })); }); - it("Should successfully change the description", async() => { - await I_CappedSTOFactory.changeDescription("It is only a STO", {from: token_owner}); - assert.equal(await I_CappedSTOFactory.getDescription.call(), - "It is only a STO", - "Description doesn't get changed"); + it("Should successfully change the description", async () => { + await I_CappedSTOFactory.changeDescription("It is only a STO", { from: token_owner }); + assert.equal(await I_CappedSTOFactory.getDescription.call(), "It is only a STO", "Description doesn't get changed"); }); - it("Should fail to change the name -- bad owner", async() => { - - await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from:account_investor1})); + it("Should fail to change the name -- bad owner", async () => { + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), { from: account_investor1 })); }); - it("Should fail to change the name -- zero length", async() => { - - await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(""), {from: token_owner})); + it("Should fail to change the name -- zero length", async () => { + await catchRevert(I_CappedSTOFactory.changeName(web3.utils.stringToHex(""), { from: token_owner })); }); - it("Should successfully change the name", async() => { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), {from: token_owner}); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), - "STOCapped", - "Name doesn't get changed"); + it("Should successfully change the name", async () => { + await I_CappedSTOFactory.changeName(web3.utils.stringToHex("STOCapped"), { from: token_owner }); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), "STOCapped", "Name doesn't get changed"); }); - it("Should successfully change the name", async() => { - await I_CappedSTOFactory.changeName(web3.utils.stringToHex("CappedSTO"), {from: token_owner}); - assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), - "CappedSTO", - "Name doesn't get changed"); + it("Should successfully change the name", async () => { + await I_CappedSTOFactory.changeName(web3.utils.stringToHex("CappedSTO"), { from: token_owner }); + assert.equal(web3.utils.hexToString(await I_CappedSTOFactory.getName.call()), "CappedSTO", "Name doesn't get changed"); }); + }); - }); - - describe("Test cases for the get functions of the capped sto", async() => { - it("Should verify the cap reached or not", async() => { + describe("Test cases for the get functions of the capped sto", async () => { + it("Should verify the cap reached or not", async () => { assert.isTrue(await I_CappedSTO_Array_POLY[0].capReached.call()); - }); + }); - it("Should get the raised amount of ether", async() => { - assert.equal(await I_CappedSTO_Array_POLY[0].getRaised.call(ETH), web3.utils.toWei('0','ether')); - }); + it("Should get the raised amount of ether", async () => { + assert.equal(await I_CappedSTO_Array_POLY[0].getRaised.call(ETH), web3.utils.toWei("0", "ether")); + }); - it("Should get the raised amount of poly", async() => { - assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei('10000','ether')); - }); + it("Should get the raised amount of poly", async () => { + assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).toNumber(), web3.utils.toWei("10000", "ether")); + }); - it("Should get the investors", async() => { - assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(),2); - }); + it("Should get the investors", async () => { + assert.equal(await I_CappedSTO_Array_POLY[0].investorCount.call(), 2); + }); - it("Should get the listed permissions", async() => { + it("Should get the listed permissions", async () => { let tx = await I_CappedSTO_Array_POLY[0].getPermissions.call(); - assert.equal(tx.length,0); - }); + assert.equal(tx.length, 0); + }); - it("Should get the metrics of the STO", async() => { + it("Should get the metrics of the STO", async () => { let metrics = await I_CappedSTO_Array_POLY[0].getSTODetails.call(); assert.isTrue(metrics[7]); - }); - - }); + }); + }); }); - describe("Attach second POLY STO module", async() => { + describe("Attach second POLY STO module", async () => { it("Should successfully attach a second STO to the security token", async () => { startTime_POLY2 = latestTime() + duration.days(1); endTime_POLY2 = startTime_POLY2 + duration.days(30); await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); - await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner}); + await I_PolyToken.transfer(I_SecurityToken_POLY.address, cappedSTOSetupCost, { from: token_owner }); - let bytesSTO = encodeModuleCall(STOParameters, [startTime_POLY2, endTime_POLY2, P_cap, P_rate, [P_fundRaiseType], account_fundsReceiver]); + let bytesSTO = encodeModuleCall(STOParameters, [ + startTime_POLY2, + endTime_POLY2, + P_cap, + P_rate, + [P_fundRaiseType], + account_fundsReceiver + ]); const tx = await I_SecurityToken_POLY.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.hexToString(tx.logs[3].args._name),"CappedSTO","CappedSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); I_CappedSTO_Array_POLY.push(CappedSTO.at(tx.logs[3].args._module)); }); - it("Should verify the configuration of the STO", async() => { + it("Should verify the configuration of the STO", async () => { assert.equal( (await I_CappedSTO_Array_POLY[1].startTime.call()).toNumber(), startTime_POLY2, @@ -1013,11 +927,7 @@ contract('CappedSTO', accounts => { BigNumber(P_cap).dividedBy(new BigNumber(10).pow(18)), "STO Configuration doesn't set as expected" ); - assert.equal( - await I_CappedSTO_Array_POLY[1].rate.call(), - P_rate, - "STO Configuration doesn't set as expected" - ); + assert.equal(await I_CappedSTO_Array_POLY[1].rate.call(), P_rate, "STO Configuration doesn't set as expected"); assert.equal( await I_CappedSTO_Array_POLY[1].fundRaiseTypes.call(P_fundRaiseType), true, @@ -1025,51 +935,37 @@ contract('CappedSTO', accounts => { ); }); - it("Should successfully invest in second STO", async() => { - + it("Should successfully invest in second STO", async () => { const polyToInvest = 1000; const stToReceive = polyToInvest * P_rate; - await I_PolyToken.getTokens((polyToInvest * Math.pow(10, 18)), account_investor3); + await I_PolyToken.getTokens(polyToInvest * Math.pow(10, 18), account_investor3); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - P_fromTime, - P_toTime, - P_expiryTime, - true, - { - from: account_issuer, - gas: 500000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, P_fromTime, P_toTime, P_expiryTime, true, { + from: account_issuer, + gas: 500000 + }); // Jump time to beyond STO start await increaseTime(duration.days(2)); - await I_PolyToken.approve(I_CappedSTO_Array_POLY[1].address, (polyToInvest * Math.pow(10, 18)), { from: account_investor3 }); + await I_PolyToken.approve(I_CappedSTO_Array_POLY[1].address, polyToInvest * Math.pow(10, 18), { from: account_investor3 }); // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[1].buyTokensWithPoly( - (polyToInvest * Math.pow(10, 18)), - { - from : account_investor3, - gas: 6000000 - } - ); + await I_CappedSTO_Array_POLY[1].buyTokensWithPoly(polyToInvest * Math.pow(10, 18), { + from: account_investor3, + gas: 6000000 + }); assert.equal( - (await I_CappedSTO_Array_POLY[1].getRaised.call(POLY)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_CappedSTO_Array_POLY[1].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), polyToInvest ); assert.equal(await I_CappedSTO_Array_POLY[1].investorCount.call(), 1); assert.equal( - (await I_SecurityToken_POLY.balanceOf(account_investor3)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_SecurityToken_POLY.balanceOf(account_investor3)).dividedBy(new BigNumber(10).pow(18)).toNumber(), stToReceive ); }); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index fddbf8e3a..0c5fa84f6 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -1,17 +1,16 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { setUpPolymathNetwork } from './helpers/createInstances'; +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('Checkpoints', accounts => { +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port +contract("Checkpoints", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -61,10 +60,10 @@ contract('Checkpoints', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -79,9 +78,19 @@ contract('Checkpoints', accounts => { // Step 1: Deploy the genral PM ecosystem let instances = await setUpPolymathNetwork(account_polymath, token_owner); - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; - + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // Printing all the contract addresses console.log(` @@ -99,50 +108,43 @@ contract('Checkpoints', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should set controller to token owner", async () => { - await I_SecurityToken.setController(token_owner, {from: token_owner}); + await I_SecurityToken.setController(token_owner, { from: token_owner }); }); it("Should intialize the auto attached modules", async () => { let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - }); - describe("Buy tokens using on-chain whitelist", async() => { - - it("Should Buy the tokens", async() => { + describe("Buy tokens using on-chain whitelist", async () => { + it("Should Buy the tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -154,20 +156,22 @@ contract('Checkpoints', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('10', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("10", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('10', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("10", "ether")); }); - it("Should Buy some more tokens", async() => { + it("Should Buy some more tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -179,21 +183,22 @@ contract('Checkpoints', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('10', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("10", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('10', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("10", "ether")); }); - it("Add a new token holder", async() => { - + it("Add a new token holder", async () => { let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor3, latestTime(), @@ -203,22 +208,24 @@ contract('Checkpoints', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor3.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('10', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor3, web3.utils.toWei("10", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('10', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei("10", "ether")); }); - it("Fuzz test balance checkpoints", async() => { - await I_SecurityToken.changeGranularity(1, {from: token_owner}); + it("Fuzz test balance checkpoints", async () => { + await I_SecurityToken.changeGranularity(1, { from: token_owner }); let cps = []; let ts = []; for (let j = 0; j < 10; j++) { @@ -228,10 +235,17 @@ contract('Checkpoints', accounts => { let totalSupply = BigNumber(await I_SecurityToken.totalSupply()); cps.push([balance1, balance2, balance3]); ts.push(totalSupply); - console.log("Checkpoint: " + (j + 1) + " Balances: " + JSON.stringify(cps[cps.length - 1]) + " TotalSupply: " + JSON.stringify(totalSupply)); + console.log( + "Checkpoint: " + + (j + 1) + + " Balances: " + + JSON.stringify(cps[cps.length - 1]) + + " TotalSupply: " + + JSON.stringify(totalSupply) + ); await I_SecurityToken.createCheckpoint({ from: token_owner }); - let checkpointTimes = (await I_SecurityToken.getCheckpointTimes()); - assert.equal(checkpointTimes.length, (j + 1)); + let checkpointTimes = await I_SecurityToken.getCheckpointTimes(); + assert.equal(checkpointTimes.length, j + 1); console.log("Checkpoint Times: " + checkpointTimes); let txs = Math.floor(Math.random() * 3); for (let i = 0; i < txs; i++) { @@ -239,31 +253,35 @@ contract('Checkpoints', accounts => { let receiver; let s = Math.random() * 3; if (s < 1) { - sender = account_investor1; + sender = account_investor1; } else if (s < 2) { - sender = account_investor2; + sender = account_investor2; } else { - sender = account_investor3; + sender = account_investor3; } let r = Math.random() * 3; if (r < 1) { - receiver = account_investor1; + receiver = account_investor1; } else if (r < 2) { - receiver = account_investor2; + receiver = account_investor2; } else { - receiver = account_investor3; + receiver = account_investor3; } let m = Math.random(); - let amount = BigNumber(await I_SecurityToken.balanceOf(sender)).mul(Math.random().toFixed(10)).toFixed(0); + let amount = BigNumber(await I_SecurityToken.balanceOf(sender)) + .mul(Math.random().toFixed(10)) + .toFixed(0); if (m > 0.8) { - console.log("Sending full balance"); - amount = BigNumber(await I_SecurityToken.balanceOf(sender)); + console.log("Sending full balance"); + amount = BigNumber(await I_SecurityToken.balanceOf(sender)); } console.log("Sender: " + sender + " Receiver: " + receiver + " Amount: " + JSON.stringify(amount)); await I_SecurityToken.transfer(receiver, amount, { from: sender }); } if (Math.random() > 0.5) { - let n = BigNumber(Math.random().toFixed(10)).mul(10**17).toFixed(0); + let n = BigNumber(Math.random().toFixed(10)) + .mul(10 ** 17) + .toFixed(0); let p = Math.random() * 3; let r = Math.random() * 3; let minter; @@ -278,7 +296,7 @@ contract('Checkpoints', accounts => { await I_SecurityToken.mint(minter, n, { from: token_owner }); } if (Math.random() > 0.5) { - let n = BigNumber(Math.random().toFixed(10)).mul(10**17); + let n = BigNumber(Math.random().toFixed(10)).mul(10 ** 17); let p = Math.random() * 3; let r = Math.random() * 3; let burner; @@ -328,8 +346,6 @@ contract('Checkpoints', accounts => { assert.isTrue(balances[l].eq(cps[k][l])); } } - }); }); - }); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 101407899..07559d189 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -1,21 +1,20 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeModuleCall } from './helpers/encodeCall'; -import { setUpPolymathNetwork } from './helpers/createInstances'; -import { catchRevert } from './helpers/exceptions'; - -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const CountTransferManagerFactory = artifacts.require('./CountTransferManagerFactory.sol'); -const CountTransferManager = artifacts.require('./CountTransferManager'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('CountTransferManager', accounts => { - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeModuleCall } from "./helpers/encodeCall"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { catchRevert } from "./helpers/exceptions"; + +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); +const CountTransferManager = artifacts.require("./CountTransferManager"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("CountTransferManager", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -69,10 +68,10 @@ contract('CountTransferManager', accounts => { const initRegFee = web3.utils.toWei("250"); // CountTransferManager details - const holderCount = 2; // Maximum number of token holders - let bytesSTO = encodeModuleCall(['uint256'], [holderCount]); + const holderCount = 2; // Maximum number of token holders + let bytesSTO = encodeModuleCall(["uint256"], [holderCount]); - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -86,11 +85,22 @@ contract('CountTransferManager', accounts => { // Step 1: Deploy the genral PM ecosystem let instances = await setUpPolymathNetwork(account_polymath, token_owner); - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 2: Deploy the CountTransferManager - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_CountTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -98,7 +108,9 @@ contract('CountTransferManager', accounts => { ); // STEP 3: Deploy Paid the CountTransferManager - P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); + P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, { + from: account_polymath + }); assert.notEqual( P_CountTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -130,55 +142,57 @@ contract('CountTransferManager', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the CountTransferManager factory with the security token", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + await catchRevert( + I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }) + ); }); it("Should successfully attach the CountTransferManager factory with the security token", async () => { let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + const tx = await I_SecurityToken.addModule( + P_CountTransferManagerFactory.address, + bytesSTO, + web3.utils.toWei("500", "ether"), + 0, + { from: token_owner } + ); assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "CountTransferManager", "CountTransferManagerFactory module was not added" ); @@ -190,8 +204,7 @@ contract('CountTransferManager', accounts => { const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "CountTransferManager", "CountTransferManager module was not added" ); @@ -199,9 +212,8 @@ contract('CountTransferManager', accounts => { }); }); - describe("Buy tokens using on-chain whitelist", async() => { - - it("Should Buy the tokens", async() => { + describe("Buy tokens using on-chain whitelist", async () => { + it("Should Buy the tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -213,23 +225,25 @@ contract('CountTransferManager', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(5000); // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Should Buy some more tokens", async() => { + it("Should Buy some more tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -241,20 +255,22 @@ contract('CountTransferManager', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("2", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Should fail to buy some more tokens (more than 2 holders)", async() => { + it("Should fail to buy some more tokens (more than 2 holders)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor3, @@ -265,106 +281,94 @@ contract('CountTransferManager', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor3.toLowerCase(), + "Failed in adding the investor in whitelist" + ); - - await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('3', 'ether'), { from: token_owner })); + await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei("3", "ether"), { from: token_owner })); }); - - it("Should still be able to add to original token holders", async() => { + it("Should still be able to add to original token holders", async () => { // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("2", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('4', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("4", "ether")); }); - it("Should still be able to transfer between existing token holders before count change", async() => { + it("Should still be able to transfer between existing token holders before count change", async () => { // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("2", "ether"), { from: account_investor2 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Should fail in modifying the holder count", async() => { - + it("Should fail in modifying the holder count", async () => { await catchRevert(I_CountTransferManager.changeHolderCount(1, { from: account_investor1 })); - }) + }); - it("Modify holder count to 1", async() => { + it("Modify holder count to 1", async () => { // Add the Investor in to the whitelist // Mint some tokens await I_CountTransferManager.changeHolderCount(1, { from: token_owner }); - assert.equal( - (await I_CountTransferManager.maxHolderCount()).toNumber(), - 1 - ); + assert.equal((await I_CountTransferManager.maxHolderCount()).toNumber(), 1); }); - it("Should still be able to transfer between existing token holders after count change", async() => { + it("Should still be able to transfer between existing token holders after count change", async () => { // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("2", "ether"), { from: account_investor1 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('4', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("4", "ether")); }); - it("Should not be able to transfer to a new token holder", async() => { - - // await I_CountTransferManager.unpause({from: token_owner}); - await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor2 })); - + it("Should not be able to transfer to a new token holder", async () => { + // await I_CountTransferManager.unpause({from: token_owner}); + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei("2", "ether"), { from: account_investor2 })); }); - it("Should be able to consolidate balances", async() => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + it("Should be able to consolidate balances", async () => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 }); }); - it("Should get the permission list", async() => { + it("Should get the permission list", async () => { let perm = await I_CountTransferManager.getPermissions.call(); assert.equal(perm.length, 1); }); - describe("Test cases for the factory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_CountTransferManagerFactory.setupCost.call(),0); - assert.equal((await I_CountTransferManagerFactory.getTypes.call())[0],2); - assert.equal(web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "CountTransferManager", - "Wrong Module added"); - assert.equal(await I_CountTransferManagerFactory.getDescription.call(), - "Restrict the number of investors", - "Wrong Module added"); - assert.equal(await I_CountTransferManagerFactory.getTitle.call(), - "Count Transfer Manager", - "Wrong Module added"); - assert.equal(await I_CountTransferManagerFactory.getInstructions.call(), - "Allows an issuer to restrict the total number of non-zero token holders", - "Wrong Module added"); - + describe("Test cases for the factory", async () => { + it("should get the exact details of the factory", async () => { + assert.equal(await I_CountTransferManagerFactory.setupCost.call(), 0); + assert.equal((await I_CountTransferManagerFactory.getTypes.call())[0], 2); + assert.equal( + web3.utils.toAscii(await I_CountTransferManagerFactory.getName.call()).replace(/\u0000/g, ""), + "CountTransferManager", + "Wrong Module added" + ); + assert.equal( + await I_CountTransferManagerFactory.getDescription.call(), + "Restrict the number of investors", + "Wrong Module added" + ); + assert.equal(await I_CountTransferManagerFactory.getTitle.call(), "Count Transfer Manager", "Wrong Module added"); + assert.equal( + await I_CountTransferManagerFactory.getInstructions.call(), + "Allows an issuer to restrict the total number of non-zero token holders", + "Wrong Module added" + ); }); - it("Should get the tags of the factory", async() => { + it("Should get the tags of the factory", async () => { let tags = await I_CountTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''),"Count"); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ""), "Count"); }); }); - }); - }); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 2f490956a..7b67bc414 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -1,20 +1,19 @@ -import latestTime from './helpers/latestTime'; -import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { catchRevert } from './helpers/exceptions'; -import { setUpPolymathNetwork } from './helpers/createInstances'; - -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const ERC20DividendCheckpointFactory = artifacts.require('./ERC20DividendCheckpointFactory.sol'); -const ERC20DividendCheckpoint = artifacts.require('./ERC20DividendCheckpoint'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('ERC20DividendCheckpoint', accounts => { - +import latestTime from "./helpers/latestTime"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; + +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpointFactory.sol"); +const ERC20DividendCheckpoint = artifacts.require("./ERC20DividendCheckpoint"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("ERC20DividendCheckpoint", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -70,7 +69,7 @@ contract('ERC20DividendCheckpoint', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -86,11 +85,28 @@ contract('ERC20DividendCheckpoint', accounts => { // Step 1: Deploy the genral PM ecosystem let instances = await setUpPolymathNetwork(account_polymath, token_owner); - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 6: Deploy the ERC20DividendCheckpoint - P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new( + I_PolyToken.address, + web3.utils.toWei("500", "ether"), + 0, + 0, + { from: account_polymath } + ); assert.notEqual( P_ERC20DividendCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -98,22 +114,24 @@ contract('ERC20DividendCheckpoint', accounts => { ); // STEP 7: Deploy the ERC20DividendCheckpoint - I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_ERC20DividendCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "ERC20DividendCheckpointFactory contract was not deployed" ); - // STEP 8: Register the Modules with the ModuleRegistry contract + // STEP 8: Register the Modules with the ModuleRegistry contract - // (A) : Register the ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + // (A) : Register the ERC20DividendCheckpointFactory + await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - // (B) : Register the Paid ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + // (B) : Register the Paid ERC20DividendCheckpointFactory + await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` @@ -132,11 +150,10 @@ contract('ERC20DividendCheckpoint', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -144,44 +161,42 @@ contract('ERC20DividendCheckpoint', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment", async () => { await catchRevert( - I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }) + I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }) ); }); it("Should successfully attach the ERC20DividendCheckpoint with the security token with budget", async () => { - let snapId = await takeSnapshot() + let snapId = await takeSnapshot(); await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }); assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "ERC20DividendCheckpoint", "ERC20DividendCheckpoint module was not added" ); @@ -193,8 +208,7 @@ contract('ERC20DividendCheckpoint', accounts => { const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "ERC20DividendCheckpoint", "ERC20DividendCheckpoint module was not added" ); @@ -202,9 +216,8 @@ contract('ERC20DividendCheckpoint', accounts => { }); }); - describe("Check Dividend payouts", async() => { - - it("Buy some tokens for account_investor1 (1 ETH)", async() => { + describe("Check Dividend payouts", async () => { + it("Buy some tokens for account_investor1 (1 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -216,23 +229,25 @@ contract('ERC20DividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(5000); // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Buy some tokens for account_investor2 (2 ETH)", async() => { + it("Buy some tokens for account_investor2 (2 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -244,109 +259,135 @@ contract('ERC20DividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("2", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Should fail in creating the dividend - incorrect allowance", async() => { + it("Should fail in creating the dividend - incorrect allowance", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + await I_PolyToken.getTokens(web3.utils.toWei("1.5", "ether"), token_owner); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + dividendName, + { from: token_owner } + ) ); }); - it("Should fail in creating the dividend - maturity > expiry", async() => { + it("Should fail in creating the dividend - maturity > expiry", async () => { let maturity = latestTime(); let expiry = latestTime() - duration.days(10); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei("1.5", "ether"), { from: token_owner }); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + dividendName, + { from: token_owner } + ) ); }); - it("Should fail in creating the dividend - now > expiry", async() => { + it("Should fail in creating the dividend - now > expiry", async () => { let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + dividendName, + { from: token_owner } + ) ); }); - it("Should fail in creating the dividend - bad token", async() => { + it("Should fail in creating the dividend - bad token", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei("1.5", "ether"), dividendName, { + from: token_owner + }) ); }); - it("Should fail in creating the dividend - amount is 0", async() => { + it("Should fail in creating the dividend - amount is 0", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, dividendName, { from: token_owner }) ); }); - it("Create new dividend of POLY tokens", async() => { + it("Create new dividend of POLY tokens", async () => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + dividendName, + { from: token_owner } + ); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); }); - it("Investor 1 transfers his token balance to investor 2", async() => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), {from: account_investor1}); + it("Investor 1 transfers his token balance to investor 2", async () => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 }); assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei("3", "ether")); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}) - ); + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails maturity in the future", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner })); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails not owner", async() => { + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails not owner", async () => { // Increase time by 2 day await increaseTime(duration.days(2)); - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}) - ); + await catchRevert(I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: account_temp })); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}) - ); + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails wrong index", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner })); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async () => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner, gas: 5000000}); + await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner, gas: 5000000 }); let investor1BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei("0.5", "ether")); + assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei("1", "ether")); //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); + assert.equal((await I_ERC20DividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei("1.5", "ether")); }); - it("Buy some tokens for account_temp (1 ETH)", async() => { + it("Buy some tokens for account_temp (1 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -358,54 +399,57 @@ contract('ERC20DividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), "Failed in adding the investor in whitelist"); // Mint some tokens - await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_temp, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_temp)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_temp)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Should not allow to create dividend without name", async() => { + it("Should not allow to create dividend without name", async () => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + await I_PolyToken.getTokens(web3.utils.toWei("1.5", "ether"), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei("1.5", "ether"), { from: token_owner }); await catchRevert( - I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), '', {from: token_owner}) + I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei("1.5", "ether"), "", { + from: token_owner + }) ); }); - it("Create new dividend", async() => { + it("Create new dividend", async () => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + await I_PolyToken.getTokens(web3.utils.toWei("1.5", "ether"), token_owner); // transfer approved in above test - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), dividendName, {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + dividendName, + { from: token_owner } + ); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 1"); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry", async() => { + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint - fails past expiry", async () => { await increaseTime(duration.days(12)); - await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}) - ); + await catchRevert(I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, { from: token_owner })); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoin - fails already reclaimed", async() => { - let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); - assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}) - ); + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoin - fails already reclaimed", async () => { + let tx = await I_ERC20DividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }); + assert.equal(tx.logs[0].args._claimedAmount.toNumber(), web3.utils.toWei("1.5", "ether")); + await catchRevert(I_ERC20DividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 })); }); - it("Buy some tokens for account_investor3 (7 ETH)", async() => { + it("Buy some tokens for account_investor3 (7 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -417,228 +461,282 @@ contract('ERC20DividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor3.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor3, web3.utils.toWei("7", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('7', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei("7", "ether")); }); - it("Should allow to exclude same number of address as EXCLUDED_ADDRESS_LIMIT", async() => { + it("Should allow to exclude same number of address as EXCLUDED_ADDRESS_LIMIT", async () => { let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); limit = limit.toNumber() - 1; let addresses = []; addresses.push(account_temp); - while(limit--) - addresses.push(limit); - await I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}); + while (limit--) addresses.push(limit); + await I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, { from: token_owner }); let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); assert.equal(excluded[0], account_temp); }); - it("Exclude account_temp using global exclusion list", async() => { - await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], {from: token_owner}); + it("Exclude account_temp using global exclusion list", async () => { + await I_ERC20DividendCheckpoint.setDefaultExcluded([account_temp], { from: token_owner }); let excluded = await I_ERC20DividendCheckpoint.getDefaultExcluded(); assert.equal(excluded[0], account_temp); }); - it("Should not allow to exclude more address than EXCLUDED_ADDRESS_LIMIT", async() => { + it("Should not allow to exclude more address than EXCLUDED_ADDRESS_LIMIT", async () => { let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); limit = limit.toNumber(); let addresses = []; addresses.push(account_temp); - while(limit--) - addresses.push(limit); - await catchRevert( - I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, {from: token_owner}) - ); + while (limit--) addresses.push(limit); + await catchRevert(I_ERC20DividendCheckpoint.setDefaultExcluded(addresses, { from: token_owner })); }); - it("Create another new dividend", async() => { + it("Create another new dividend", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); - let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), dividendName, {from: token_owner}); + await I_PolyToken.getTokens(web3.utils.toWei("11", "ether"), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei("11", "ether"), { from: token_owner }); + let tx = await I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("10", "ether"), + dividendName, + { from: token_owner } + ); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 2"); }); - it("should investor 3 claims dividend - fail bad index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}) - ); + it("should investor 3 claims dividend - fail bad index", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pullDividendPayment(5, { from: account_investor3, gasPrice: 0 })); }); - it("should investor 3 claims dividend", async() => { + it("should investor 3 claims dividend", async () => { console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); + await I_ERC20DividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }); let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei("7", "ether")); }); - it("should investor 3 claims dividend - fails already claimed", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}) - ); + it("should investor 3 claims dividend - fails already claimed", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 })); }); - it("should issuer pushes remain", async() => { + it("should issuer pushes remain", async () => { console.log((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber()); let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); let investorTempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); + await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); let investorTempBalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_temp)); assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('3', 'ether')); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei("3", "ether")); assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); assert.equal(investorTempBalanceAfter2.sub(investorTempBalanceAfter1).toNumber(), 0); //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('10', 'ether')); + assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei("10", "ether")); }); - - it("Delete global exclusion list", async() => { - await I_ERC20DividendCheckpoint.setDefaultExcluded([], {from: token_owner}); + it("Delete global exclusion list", async () => { + await I_ERC20DividendCheckpoint.setDefaultExcluded([], { from: token_owner }); }); - - it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); + it("Investor 2 transfers 1 ETH of his token balance to investor 1", async () => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("1", "ether"), { from: account_investor2 }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei("1", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei("2", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei("7", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei("1", "ether")); }); - it("Create another new dividend with explicit checkpoint - fails bad allowance", async() => { + it("Create another new dividend with explicit checkpoint - fails bad allowance", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); - let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); + let tx = await I_SecurityToken.createCheckpoint({ from: token_owner }); console.log(JSON.stringify(tx.logs[0].args)); console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); - await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); + await I_PolyToken.getTokens(web3.utils.toWei("20", "ether"), token_owner); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("20", "ether"), + 4, + dividendName, + { from: token_owner } + ) ); }); - it("Create another new dividend with explicit - fails maturity > expiry", async() => { + it("Create another new dividend with explicit - fails maturity > expiry", async () => { console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); let maturity = latestTime(); let expiry = latestTime() - duration.days(10); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), {from: token_owner}); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei("20", "ether"), { from: token_owner }); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("20", "ether"), + 4, + dividendName, + { from: token_owner } + ) ); }); - it("Create another new dividend with explicit - fails now > expiry", async() => { + it("Create another new dividend with explicit - fails now > expiry", async () => { console.log((await I_SecurityToken.currentCheckpointId()).toNumber()); let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 4, dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("20", "ether"), + 4, + dividendName, + { from: token_owner } + ) ); }); - it("Create another new dividend with explicit - fails bad checkpoint", async() => { + it("Create another new dividend with explicit - fails bad checkpoint", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("20", "ether"), + 5, + dividendName, + { from: token_owner } + ) ); }); - it("Set withholding tax of 20% on account_temp and 10% on investor2", async() => { - await I_ERC20DividendCheckpoint.setWithholding([account_temp, account_investor2], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}); + it("Set withholding tax of 20% on account_temp and 10% on investor2", async () => { + await I_ERC20DividendCheckpoint.setWithholding( + [account_temp, account_investor2], + [BigNumber(20 * 10 ** 16), BigNumber(10 * 10 ** 16)], + { from: token_owner } + ); }); - it("Should not allow mismatching input lengths", async() => { + it("Should not allow mismatching input lengths", async () => { await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**16), BigNumber(10*10**16)], {from: token_owner}) + I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20 * 10 ** 16), BigNumber(10 * 10 ** 16)], { + from: token_owner + }) ); }); - it("Should not allow withholding greater than limit", async() => { + it("Should not allow withholding greater than limit", async () => { + await catchRevert(I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20 * 10 ** 26)], { from: token_owner })); await catchRevert( - I_ERC20DividendCheckpoint.setWithholding([account_temp], [BigNumber(20*10**26)], {from: token_owner}) - ); - await catchRevert( - I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20*10**26), {from: token_owner}), + I_ERC20DividendCheckpoint.setWithholdingFixed([account_temp], BigNumber(20 * 10 ** 26), { from: token_owner }), "" ); }); - it("Should not create dividend with more exclusions than limit", async() => { + it("Should not create dividend with more exclusions than limit", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); - await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('11', 'ether'), {from: token_owner}); + await I_PolyToken.getTokens(web3.utils.toWei("11", "ether"), token_owner); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei("11", "ether"), { from: token_owner }); let limit = await I_ERC20DividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); limit = limit.toNumber(); let addresses = []; addresses.push(account_temp); - while(limit--) - addresses.push(limit); + while (limit--) addresses.push(limit); await catchRevert( - I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, addresses, dividendName, {from: token_owner}) + I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("10", "ether"), + 4, + addresses, + dividendName, + { from: token_owner } + ) ); }); - it("Create another new dividend with explicit checkpoint and exclusion", async() => { + it("Create another new dividend with explicit checkpoint and exclusion", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - await I_PolyToken.getTokens(web3.utils.toWei('11', 'ether'), token_owner); + await I_PolyToken.getTokens(web3.utils.toWei("11", "ether"), token_owner); //token transfer approved in above test - let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, I_PolyToken.address, web3.utils.toWei('10', 'ether'), 4, [account_investor1], dividendName, {from: token_owner}); + let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("10", "ether"), + 4, + [account_investor1], + dividendName, + { from: token_owner } + ); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 3"); }); - it("Should not allow excluded to pull Dividend Payment", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor1, gasPrice: 0}) - ); + it("Should not allow excluded to pull Dividend Payment", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor1, gasPrice: 0 })); }); - it("Investor 2 claims dividend, issuer pushes investor 1 - fails not owner", async() => { + it("Investor 2 claims dividend, issuer pushes investor 1 - fails not owner", async () => { await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}) + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1], { + from: account_investor2, + gasPrice: 0 + }) ); }); - it("Investor 2 claims dividend, issuer pushes investor 1 - fails bad index", async() => { + it("Investor 2 claims dividend, issuer pushes investor 1 - fails bad index", async () => { await catchRevert( - I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}) + I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1], { + from: token_owner, + gasPrice: 0 + }) ); }); - it("should not calculate dividend for invalid index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1) - ); + it("should not calculate dividend for invalid index", async () => { + await catchRevert(I_ERC20DividendCheckpoint.calculateDividend.call(5, account_investor1)); }); - it("should calculate dividend before the push dividend payment", async() => { + it("should calculate dividend before the push dividend payment", async () => { let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); let dividendAmount3 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor3); @@ -653,28 +751,28 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0.2", "ether")); }); - it("Investor 2 claims dividend", async() => { + it("Investor 2 claims dividend", async () => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); - await I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor2, gasPrice: 0}); + await I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.8', 'ether')); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei("1.8", "ether")); assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); }); - it("Should issuer pushes temp investor - investor1 excluded", async() => { + it("Should issuer pushes temp investor - investor1 excluded", async () => { let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); let tempBalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_temp)); - await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(3, [account_temp, account_investor1], {from: token_owner}); + await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(3, [account_temp, account_investor1], { from: token_owner }); let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); @@ -682,114 +780,101 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('0.8', 'ether')); + assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei("0.8", "ether")); //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); + assert.equal((await I_ERC20DividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei("3", "ether")); }); - it("should calculate dividend after the push dividend payment", async() => { + it("should calculate dividend after the push dividend payment", async () => { let dividendAmount1 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor1); let dividendAmount2 = await I_ERC20DividendCheckpoint.calculateDividend.call(3, account_investor2); assert.equal(dividendAmount1[0].toNumber(), 0); assert.equal(dividendAmount2[0].toNumber(), 0); }); - it("Should not allow reclaiming withholding tax with incorrect index", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}) - ); + it("Should not allow reclaiming withholding tax with incorrect index", async () => { + await catchRevert(I_ERC20DividendCheckpoint.withdrawWithholding(300, { from: token_owner, gasPrice: 0 })); }); - it("Issuer reclaims withholding tax", async() => { + it("Issuer reclaims withholding tax", async () => { let issuerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); - await I_ERC20DividendCheckpoint.withdrawWithholding(3, {from: token_owner, gasPrice: 0}); + await I_ERC20DividendCheckpoint.withdrawWithholding(3, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.4', 'ether')) + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0.4", "ether")); }); - it("Issuer unable to reclaim dividend (expiry not passed)", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner}) - ); + it("Issuer unable to reclaim dividend (expiry not passed)", async () => { + await catchRevert(I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner })); }); - it("Issuer is unable to reclaim invalid dividend", async() => { + it("Issuer is unable to reclaim invalid dividend", async () => { await increaseTime(11 * 24 * 60 * 60); - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}) - ); + await catchRevert(I_ERC20DividendCheckpoint.reclaimDividend(8, { from: token_owner, gasPrice: 0 })); }); - it("Investor 3 unable to pull dividend after expiry", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}) - ); + it("Investor 3 unable to pull dividend after expiry", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 })); }); - it("Issuer is able to reclaim dividend after expiry", async() => { + it("Issuer is able to reclaim dividend after expiry", async () => { let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); - await I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); + await I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }); let tokenOwnerAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); - assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei("7", "ether")); }); - - it("Issuer is unable to reclaim already reclaimed dividend", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}) - ); + it("Issuer is unable to reclaim already reclaimed dividend", async () => { + await catchRevert(I_ERC20DividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 })); }); - it("Investor 3 unable to pull dividend after reclaiming", async() => { - await catchRevert( - I_ERC20DividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0}) - ); + it("Investor 3 unable to pull dividend after reclaiming", async () => { + await catchRevert(I_ERC20DividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 })); }); - it("Should give the right dividend index", async() => { + it("Should give the right dividend index", async () => { let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(3); assert.equal(index[0], 2); }); - it("Should give the right dividend index", async() => { + it("Should give the right dividend index", async () => { let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(8); assert.equal(index.length, 0); }); - it("Get the init data", async() => { + it("Get the init data", async () => { let tx = await I_ERC20DividendCheckpoint.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ""), 0); }); - it("Should get the listed permissions", async() => { + it("Should get the listed permissions", async () => { let tx = await I_ERC20DividendCheckpoint.getPermissions.call(); - assert.equal(tx.length,1); + assert.equal(tx.length, 1); }); - describe("Test cases for the ERC20DividendCheckpointFactory", async() => { - it("should get the exact details of the factory", async() => { + describe("Test cases for the ERC20DividendCheckpointFactory", async () => { + it("should get the exact details of the factory", async () => { assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); assert.equal((await I_ERC20DividendCheckpointFactory.getTypes.call())[0], 4); assert.equal(await I_ERC20DividendCheckpointFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()) - .replace(/\u0000/g, ''), - "ERC20DividendCheckpoint", - "Wrong Module added"); - assert.equal(await I_ERC20DividendCheckpointFactory.getDescription.call(), - "Create ERC20 dividends for token holders at a specific checkpoint", - "Wrong Module added"); - assert.equal(await I_ERC20DividendCheckpointFactory.getTitle.call(), - "ERC20 Dividend Checkpoint", - "Wrong Module added"); - assert.equal(await I_ERC20DividendCheckpointFactory.getInstructions.call(), - "Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", - "Wrong Module added"); + assert.equal( + web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()).replace(/\u0000/g, ""), + "ERC20DividendCheckpoint", + "Wrong Module added" + ); + assert.equal( + await I_ERC20DividendCheckpointFactory.getDescription.call(), + "Create ERC20 dividends for token holders at a specific checkpoint", + "Wrong Module added" + ); + assert.equal(await I_ERC20DividendCheckpointFactory.getTitle.call(), "ERC20 Dividend Checkpoint", "Wrong Module added"); + assert.equal( + await I_ERC20DividendCheckpointFactory.getInstructions.call(), + "Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", + "Wrong Module added" + ); let tags = await I_ERC20DividendCheckpointFactory.getTags.call(); assert.equal(tags.length, 3); - }); }); - }); - -}); \ No newline at end of file +}); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index d5545c082..b27219692 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -1,31 +1,30 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const EtherDividendCheckpointFactory = artifacts.require('./EtherDividendCheckpointFactory.sol'); -const EtherDividendCheckpoint = artifacts.require('./EtherDividendCheckpoint'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('EtherDividendCheckpoint', accounts => { - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); +const EtherDividendCheckpoint = artifacts.require("./EtherDividendCheckpoint"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("EtherDividendCheckpoint", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -81,10 +80,10 @@ contract('EtherDividendCheckpoint', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -97,35 +96,33 @@ contract('EtherDividendCheckpoint', accounts => { account_investor4 = accounts[9]; account_temp = accounts[2]; - // ----------- POLYMATH NETWORK Configuration ------------ + // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -135,7 +132,9 @@ contract('EtherDividendCheckpoint', accounts => { // STEP 5: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -144,7 +143,13 @@ contract('EtherDividendCheckpoint', accounts => { ); // STEP 4: Deploy the ERC20DividendCheckpoint - P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new( + I_PolyToken.address, + web3.utils.toWei("500", "ether"), + 0, + 0, + { from: account_polymath } + ); assert.notEqual( P_EtherDividendCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -152,63 +157,70 @@ contract('EtherDividendCheckpoint', accounts => { ); // STEP 4: Deploy the EtherDividendCheckpoint - I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_EtherDividendCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "EtherDividendCheckpointFactory contract was not deployed" ); - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 7: Deploy the SecurityTokenRegistry contract + // Step 6: Deploy the STFactory contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 7: Deploy the SecurityTokenRegistry contract - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the EtherDividendCheckpointFactory - await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // (C) : Register the Paid EtherDividendCheckpointFactory - await I_MRProxied.registerModule(P_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the EtherDividendCheckpointFactory + await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + + // (C) : Register the Paid EtherDividendCheckpointFactory + await I_MRProxied.registerModule(P_EtherDividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` @@ -229,11 +241,10 @@ contract('EtherDividendCheckpoint', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -241,44 +252,43 @@ contract('EtherDividendCheckpoint', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + await catchRevert( + I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }) + ); }); it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }); assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "EtherDividendCheckpoint", "EtherDividendCheckpoint module was not added" ); @@ -290,8 +300,7 @@ contract('EtherDividendCheckpoint', accounts => { const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, "", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "EtherDividendCheckpoint", "EtherDividendCheckpoint module was not added" ); @@ -299,9 +308,8 @@ contract('EtherDividendCheckpoint', accounts => { }); }); - describe("Check Dividend payouts", async() => { - - it("Buy some tokens for account_investor1 (1 ETH)", async() => { + describe("Check Dividend payouts", async () => { + it("Buy some tokens for account_investor1 (1 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -313,23 +321,25 @@ contract('EtherDividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(5000); // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Buy some tokens for account_investor2 (2 ETH)", async() => { + it("Buy some tokens for account_investor2 (2 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -341,116 +351,129 @@ contract('EtherDividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("2", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Should fail in creating the dividend", async() => { - + it("Should fail in creating the dividend", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner})); + await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { from: token_owner })); }); - it("Should fail in creating the dividend", async() => { - + it("Should fail in creating the dividend", async () => { let maturity = latestTime(); let expiry = latestTime() - duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); + await catchRevert( + I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei("1.5", "ether") + }) + ); }); - it("Should fail in creating the dividend", async() => { - + it("Should fail in creating the dividend", async () => { let maturity = latestTime() - duration.days(2); let expiry = latestTime() - duration.days(1); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); + await catchRevert( + I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei("1.5", "ether") + }) + ); }); - it("Set withholding tax of 20% on investor 2", async() => { - await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(20*10**16), {from: token_owner}); + it("Set withholding tax of 20% on investor 2", async () => { + await I_EtherDividendCheckpoint.setWithholdingFixed([account_investor2], BigNumber(20 * 10 ** 16), { from: token_owner }); }); - it("Should fail in creating the dividend", async() => { - + it("Should fail in creating the dividend", async () => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividend(maturity, expiry, '', {from: token_owner, value: web3.utils.toWei('1.5', 'ether')})); + await catchRevert( + I_EtherDividendCheckpoint.createDividend(maturity, expiry, "", { + from: token_owner, + value: web3.utils.toWei("1.5", "ether") + }) + ); }); - it("Create new dividend", async() => { + it("Create new dividend", async () => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei("1.5", "ether") + }); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); assert.equal(tx.logs[0].args._name.toString(), dividendName, "Dividend name incorrect in event"); }); - it("Investor 1 transfers his token balance to investor 2", async() => { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), {from: account_investor1}); + it("Investor 1 transfers his token balance to investor 2", async () => { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 }); assert.equal(await I_SecurityToken.balanceOf(account_investor1), 0); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('3', 'ether')); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei("3", "ether")); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async () => { + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner })); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async () => { // Increase time by 2 day await increaseTime(duration.days(2)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp})); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: account_temp })); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner})); + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async () => { + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner })); }); - it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async () => { let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); - await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); + await I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner }); let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); - assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei('0.8', 'ether')); + assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei("0.5", "ether")); + assert.equal(investor2BalanceAfter.sub(investor2Balance).toNumber(), web3.utils.toWei("0.8", "ether")); //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei('1.5', 'ether')); + assert.equal((await I_EtherDividendCheckpoint.dividends(0))[5].toNumber(), web3.utils.toWei("1.5", "ether")); }); - it("Should not allow reclaiming withholding tax with incorrect index", async() => { + it("Should not allow reclaiming withholding tax with incorrect index", async () => { await catchRevert( - I_EtherDividendCheckpoint.withdrawWithholding(300, {from: token_owner, gasPrice: 0}), + I_EtherDividendCheckpoint.withdrawWithholding(300, { from: token_owner, gasPrice: 0 }), "tx -> failed because dividend index is not valid" ); }); - it("Issuer reclaims withholding tax", async() => { + it("Issuer reclaims withholding tax", async () => { let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.2', 'ether')) + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0.2", "ether")); }); - it("No more withholding tax to withdraw", async() => { + it("No more withholding tax to withdraw", async () => { let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0", "ether")); }); - it("Buy some tokens for account_temp (1 ETH)", async() => { + it("Buy some tokens for account_temp (1 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -462,47 +485,46 @@ contract('EtherDividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); assert.equal(tx.logs[0].args._investor.toLowerCase(), account_temp.toLowerCase(), "Failed in adding the investor in whitelist"); // Mint some tokens - await I_SecurityToken.mint(account_temp, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_temp, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_temp)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_temp)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Create new dividend", async() => { + it("Create new dividend", async () => { let maturity = latestTime() + duration.days(1); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('1.5', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei("1.5", "ether") + }); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 2"); }); - it("Issuer pushes dividends fails due to passed expiry", async() => { - + it("Issuer pushes dividends fails due to passed expiry", async () => { await increaseTime(duration.days(12)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner})); + await catchRevert(I_EtherDividendCheckpoint.pushDividendPayment(0, 0, 10, { from: token_owner })); }); - it("Issuer reclaims dividend", async() => { - - let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000}); - assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, {from: token_owner, gas: 500000})); + it("Issuer reclaims dividend", async () => { + let tx = await I_EtherDividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 }); + assert.equal(tx.logs[0].args._claimedAmount.toNumber(), web3.utils.toWei("1.5", "ether")); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(1, { from: token_owner, gas: 500000 })); }); - it("Still no more withholding tax to withdraw", async() => { + it("Still no more withholding tax to withdraw", async () => { let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0", "ether")); }); - it("Buy some tokens for account_investor3 (7 ETH)", async() => { + it("Buy some tokens for account_investor3 (7 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -514,158 +536,191 @@ contract('EtherDividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor3.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('7', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor3, web3.utils.toWei("7", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('7', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei("7", "ether")); }); - it("Create another new dividend", async() => { + it("Create another new dividend", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividend(maturity, expiry, dividendName, { + from: token_owner, + value: web3.utils.toWei("11", "ether") + }); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 3, "Dividend should be created at checkpoint 3"); }); - it("should investor 3 claims dividend - fails bad index", async() => { - + it("should investor 3 claims dividend - fails bad index", async () => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0})); + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(5, { from: account_investor3, gasPrice: 0 })); }); - it("Should investor 3 claims dividend", async() => { + it("Should investor 3 claims dividend", async () => { let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); - await I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0}); + await I_EtherDividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 }); let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei("7", "ether")); }); - it("Still no more withholding tax to withdraw", async() => { + it("Still no more withholding tax to withdraw", async () => { let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(0, {from: token_owner, gasPrice: 0}); + await I_EtherDividendCheckpoint.withdrawWithholding(0, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0', 'ether')) + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0", "ether")); }); - it("should investor 3 claims dividend", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, {from: account_investor3, gasPrice: 0})); + it("should investor 3 claims dividend", async () => { + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(2, { from: account_investor3, gasPrice: 0 })); }); - it("Issuer pushes remainder", async() => { + it("Issuer pushes remainder", async () => { let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); - await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); + await I_EtherDividendCheckpoint.pushDividendPayment(2, 0, 10, { from: token_owner }); let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei('2.4', 'ether')); + assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), web3.utils.toWei("2.4", "ether")); assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei('11', 'ether')); + assert.equal((await I_EtherDividendCheckpoint.dividends(2))[5].toNumber(), web3.utils.toWei("11", "ether")); }); - it("Issuer withdraws new withholding tax", async() => { + it("Issuer withdraws new withholding tax", async () => { let issuerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.withdrawWithholding(2, {from: token_owner, gasPrice: 0}); + await I_EtherDividendCheckpoint.withdrawWithholding(2, { from: token_owner, gasPrice: 0 }); let issuerBalanceAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei('0.6', 'ether')) + assert.equal(issuerBalanceAfter.sub(issuerBalance).toNumber(), web3.utils.toWei("0.6", "ether")); }); - it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + it("Investor 2 transfers 1 ETH of his token balance to investor 1", async () => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("1", "ether"), { from: account_investor2 }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei("1", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei("2", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei("7", "ether")); }); - it("Create another new dividend with no value - fails", async() => { - + it("Create another new dividend with no value - fails", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); - let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: 0})); + let tx = await I_SecurityToken.createCheckpoint({ from: token_owner }); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { from: token_owner, value: 0 }) + ); }); - it("Create another new dividend with explicit", async() => { - + it("Create another new dividend with explicit", async () => { let maturity = latestTime(); let expiry = latestTime() - duration.days(10); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { + from: token_owner, + value: web3.utils.toWei("11", "ether") + }) + ); }); - it("Create another new dividend with bad expirty - fails", async() => { - + it("Create another new dividend with bad expirty - fails", async () => { let maturity = latestTime() - duration.days(5); let expiry = latestTime() - duration.days(2); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 4, dividendName, { + from: token_owner, + value: web3.utils.toWei("11", "ether") + }) + ); }); - it("Create another new dividend with bad checkpoint in the future - fails", async() => { - + it("Create another new dividend with bad checkpoint in the future - fails", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(2); - await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, {from: token_owner, value: web3.utils.toWei('11', 'ether')})); + await catchRevert( + I_EtherDividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, 5, dividendName, { + from: token_owner, + value: web3.utils.toWei("11", "ether") + }) + ); }); - it("Should not create dividend with more exclusions than limit", async() => { + it("Should not create dividend with more exclusions than limit", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - await I_SecurityToken.createCheckpoint({from: token_owner}); + await I_SecurityToken.createCheckpoint({ from: token_owner }); let limit = await I_EtherDividendCheckpoint.EXCLUDED_ADDRESS_LIMIT(); limit = limit.toNumber(); let addresses = []; addresses.push(account_temp); - while(limit--) - addresses.push(limit); + while (limit--) addresses.push(limit); await catchRevert( - I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, addresses, dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}), + I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, addresses, dividendName, { + from: token_owner, + value: web3.utils.toWei("10", "ether") + }), "tx -> failed because too many address excluded" ); }); - it("Create another new dividend with explicit checkpoint and excluding account_investor1", async() => { + it("Create another new dividend with explicit checkpoint and excluding account_investor1", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); //checkpoint created in above test - let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions(maturity, expiry, 4, [account_investor1], dividendName, {from: token_owner, value: web3.utils.toWei('10', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + 4, + [account_investor1], + dividendName, + { from: token_owner, value: web3.utils.toWei("10", "ether") } + ); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 4, "Dividend should be created at checkpoint 4"); }); - it("Non-owner pushes investor 1 - fails", async() => { - + it("Non-owner pushes investor 1 - fails", async () => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0})); + await catchRevert( + I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor2, account_investor1], { + from: account_investor2, + gasPrice: 0 + }) + ); }); - it("issuer pushes investor 1 with bad dividend index - fails", async() => { - + it("issuer pushes investor 1 with bad dividend index - fails", async () => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await catchRevert(I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0})); + await catchRevert( + I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(6, [account_investor2, account_investor1], { + from: token_owner, + gasPrice: 0 + }) + ); }); - it("should calculate dividend before the push dividend payment", async() => { + it("should calculate dividend before the push dividend payment", async () => { let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); let dividendAmount3 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor3); @@ -681,28 +736,28 @@ contract('EtherDividendCheckpoint', accounts => { assert.equal(dividendAmount_temp[1].toNumber(), web3.utils.toWei("0", "ether")); }); - it("Investor 2 claims dividend", async() => { + it("Investor 2 claims dividend", async () => { let investor1Balance = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2Balance = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3Balance = BigNumber(await web3.eth.getBalance(account_investor3)); let tempBalance = BigNumber(await web3.eth.getBalance(account_temp)); - await I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor2, gasPrice: 0}); + await I_EtherDividendCheckpoint.pullDividendPayment(3, { from: account_investor2, gasPrice: 0 }); let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('1.6', 'ether')); + assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei("1.6", "ether")); assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); assert.equal(tempBalanceAfter1.sub(tempBalance).toNumber(), 0); }); - it("Should issuer pushes investor 1 and temp investor", async() => { + it("Should issuer pushes investor 1 and temp investor", async () => { let investor1BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter1 = BigNumber(await web3.eth.getBalance(account_investor3)); let tempBalanceAfter1 = BigNumber(await web3.eth.getBalance(account_temp)); - await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor1, account_temp], {from: token_owner}); + await I_EtherDividendCheckpoint.pushDividendPaymentToAddresses(3, [account_investor1, account_temp], { from: token_owner }); let investor1BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceAfter2 = BigNumber(await web3.eth.getBalance(account_investor3)); @@ -710,48 +765,43 @@ contract('EtherDividendCheckpoint', accounts => { assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), 0); assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei('1', 'ether')); + assert.equal(tempBalanceAfter2.sub(tempBalanceAfter1).toNumber(), web3.utils.toWei("1", "ether")); //Check fully claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei('3', 'ether')); + assert.equal((await I_EtherDividendCheckpoint.dividends(3))[5].toNumber(), web3.utils.toWei("3", "ether")); }); - it("should calculate dividend after the push dividend payment", async() => { + it("should calculate dividend after the push dividend payment", async () => { let dividendAmount1 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor1); let dividendAmount2 = await I_EtherDividendCheckpoint.calculateDividend.call(3, account_investor2); assert.equal(dividendAmount1[0].toNumber(), 0); assert.equal(dividendAmount2[0].toNumber(), 0); - }); + }); - it("Issuer unable to reclaim dividend (expiry not passed)", async() => { - - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner})); + it("Issuer unable to reclaim dividend (expiry not passed)", async () => { + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner })); }); - it("Issuer is able to reclaim dividend after expiry", async() => { - + it("Issuer is able to reclaim dividend after expiry", async () => { await increaseTime(11 * 24 * 60 * 60); - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0})); + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(8, { from: token_owner, gasPrice: 0 })); }); - it("Issuer is able to reclaim dividend after expiry", async() => { + it("Issuer is able to reclaim dividend after expiry", async () => { let tokenOwnerBalance = BigNumber(await web3.eth.getBalance(token_owner)); - await I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0}); + await I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 }); let tokenOwnerAfter = BigNumber(await web3.eth.getBalance(token_owner)); - assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('7', 'ether')); + assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei("7", "ether")); }); - it("Issuer is able to reclaim dividend after expiry", async() => { - - await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, {from: token_owner, gasPrice: 0})); + it("Issuer is able to reclaim dividend after expiry", async () => { + await catchRevert(I_EtherDividendCheckpoint.reclaimDividend(3, { from: token_owner, gasPrice: 0 })); }); - it("Investor 3 unable to pull dividend after expiry", async() => { - - await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, {from: account_investor3, gasPrice: 0})); + it("Investor 3 unable to pull dividend after expiry", async () => { + await catchRevert(I_EtherDividendCheckpoint.pullDividendPayment(3, { from: account_investor3, gasPrice: 0 })); }); - it("Assign token balance to an address that can't receive funds", async() => { - + it("Assign token balance to an address that can't receive funds", async () => { let tx = await I_GeneralTransferManager.modifyWhitelist( I_PolyToken.address, latestTime(), @@ -761,33 +811,37 @@ contract('EtherDividendCheckpoint', accounts => { { from: account_issuer, gas: 500000 - }); - // Jump time + } + ); + // Jump time await increaseTime(5000); // Mint some tokens - await I_SecurityToken.mint(I_PolyToken.address, web3.utils.toWei('1', 'ether'), { from: token_owner }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(I_PolyToken.address), web3.utils.toWei('1', 'ether')); + await I_SecurityToken.mint(I_PolyToken.address, web3.utils.toWei("1", "ether"), { from: token_owner }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei("1", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei("2", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei("7", "ether")); + assert.equal(await I_SecurityToken.balanceOf(account_temp), web3.utils.toWei("1", "ether")); + assert.equal(await I_SecurityToken.balanceOf(I_PolyToken.address), web3.utils.toWei("1", "ether")); }); - it("Create another new dividend", async() => { + it("Create another new dividend", async () => { let maturity = latestTime(); let expiry = latestTime() + duration.days(10); - let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], dividendName, {from: token_owner, value: web3.utils.toWei('12', 'ether')}); + let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions(maturity, expiry, [], dividendName, { + from: token_owner, + value: web3.utils.toWei("12", "ether") + }); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 6, "Dividend should be created at checkpoint 6"); }); - it("Should issuer pushes all dividends", async() => { + it("Should issuer pushes all dividends", async () => { let investor1BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor2)); let investor3BalanceBefore = BigNumber(await web3.eth.getBalance(account_investor3)); let tempBalanceBefore = BigNumber(await web3.eth.getBalance(account_temp)); let tokenBalanceBefore = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); - await I_EtherDividendCheckpoint.pushDividendPayment(4, 0, 10, {from: token_owner}); + await I_EtherDividendCheckpoint.pushDividendPayment(4, 0, 10, { from: token_owner }); let investor1BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor1)); let investor2BalanceAfter = BigNumber(await web3.eth.getBalance(account_investor2)); @@ -795,60 +849,60 @@ contract('EtherDividendCheckpoint', accounts => { let tempBalanceAfter = BigNumber(await web3.eth.getBalance(account_temp)); let tokenBalanceAfter = BigNumber(await web3.eth.getBalance(I_PolyToken.address)); - assert.equal(investor1BalanceAfter.sub(investor1BalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), web3.utils.toWei('1.6', 'ether')); - assert.equal(investor3BalanceAfter.sub(investor3BalanceBefore).toNumber(), web3.utils.toWei('7', 'ether')); - assert.equal(tempBalanceAfter.sub(tempBalanceBefore).toNumber(), web3.utils.toWei('1', 'ether')); - assert.equal(tokenBalanceAfter.sub(tokenBalanceBefore).toNumber(), web3.utils.toWei('0', 'ether')); + assert.equal(investor1BalanceAfter.sub(investor1BalanceBefore).toNumber(), web3.utils.toWei("1", "ether")); + assert.equal(investor2BalanceAfter.sub(investor2BalanceBefore).toNumber(), web3.utils.toWei("1.6", "ether")); + assert.equal(investor3BalanceAfter.sub(investor3BalanceBefore).toNumber(), web3.utils.toWei("7", "ether")); + assert.equal(tempBalanceAfter.sub(tempBalanceBefore).toNumber(), web3.utils.toWei("1", "ether")); + assert.equal(tokenBalanceAfter.sub(tokenBalanceBefore).toNumber(), web3.utils.toWei("0", "ether")); //Check partially claimed - assert.equal((await I_EtherDividendCheckpoint.dividends(4))[5].toNumber(), web3.utils.toWei('11', 'ether')); + assert.equal((await I_EtherDividendCheckpoint.dividends(4))[5].toNumber(), web3.utils.toWei("11", "ether")); }); - it("Should give the right dividend index", async() => { + it("Should give the right dividend index", async () => { let index = await I_EtherDividendCheckpoint.getDividendIndex.call(3); assert.equal(index[0], 2); }); - it("Should give the right dividend index", async() => { + it("Should give the right dividend index", async () => { let index = await I_EtherDividendCheckpoint.getDividendIndex.call(8); assert.equal(index.length, 0); }); - it("Get the init data", async() => { + it("Get the init data", async () => { let tx = await I_EtherDividendCheckpoint.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ""), 0); }); - it("Should get the listed permissions", async() => { + it("Should get the listed permissions", async () => { let tx = await I_EtherDividendCheckpoint.getPermissions.call(); - assert.equal(tx.length,1); + assert.equal(tx.length, 1); }); - describe("Test cases for the EtherDividendCheckpointFactory", async() => { - it("should get the exact details of the factory", async() => { + describe("Test cases for the EtherDividendCheckpointFactory", async () => { + it("should get the exact details of the factory", async () => { assert.equal((await I_EtherDividendCheckpointFactory.setupCost.call()).toNumber(), 0); assert.equal((await I_EtherDividendCheckpointFactory.getTypes.call())[0], 4); assert.equal(await I_EtherDividendCheckpointFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()) - .replace(/\u0000/g, ''), - "EtherDividendCheckpoint", - "Wrong Module added"); - assert.equal(await I_EtherDividendCheckpointFactory.getDescription.call(), - "Create ETH dividends for token holders at a specific checkpoint", - "Wrong Module added"); - assert.equal(await I_EtherDividendCheckpointFactory.getTitle.call(), - "Ether Dividend Checkpoint", - "Wrong Module added"); - assert.equal(await I_EtherDividendCheckpointFactory.getInstructions.call(), - "Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", - "Wrong Module added"); + assert.equal( + web3.utils.toAscii(await I_EtherDividendCheckpointFactory.getName.call()).replace(/\u0000/g, ""), + "EtherDividendCheckpoint", + "Wrong Module added" + ); + assert.equal( + await I_EtherDividendCheckpointFactory.getDescription.call(), + "Create ETH dividends for token holders at a specific checkpoint", + "Wrong Module added" + ); + assert.equal(await I_EtherDividendCheckpointFactory.getTitle.call(), "Ether Dividend Checkpoint", "Wrong Module added"); + assert.equal( + await I_EtherDividendCheckpointFactory.getInstructions.call(), + "Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", + "Wrong Module added" + ); let tags = await I_EtherDividendCheckpointFactory.getTags.call(); assert.equal(tags.length, 3); - }); }); - }); - }); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 143471598..a7d2b2ee2 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -1,33 +1,32 @@ -import latestTime from './helpers/latestTime'; -import {signData} from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); -const DummySTO = artifacts.require('./DummySTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('GeneralPermissionManager', accounts => { - +import latestTime from "./helpers/latestTime"; +import { signData } from "./helpers/signData"; +import { pk } from "./helpers/testprivateKey"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); +const DummySTO = artifacts.require("./DummySTO.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("GeneralPermissionManager", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -83,17 +82,17 @@ contract('GeneralPermissionManager', accounts => { const initRegFee = web3.utils.toWei("250"); // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei("10", "ether"); const someString = "A string which is not used"; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STOParameters = ["uint256", "uint256", "uint256", "string"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -105,36 +104,33 @@ contract('GeneralPermissionManager', accounts => { account_investor2 = accounts[9]; account_delegate = accounts[7]; - // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -144,7 +140,9 @@ contract('GeneralPermissionManager', accounts => { // STEP 5: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -154,7 +152,13 @@ contract('GeneralPermissionManager', accounts => { // STEP 6: Deploy the GeneralDelegateManagerFactory - P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new( + I_PolyToken.address, + web3.utils.toWei("500", "ether"), + 0, + 0, + { from: account_polymath } + ); assert.notEqual( P_GeneralPermissionManagerFactory.address.valueOf(), @@ -164,7 +168,7 @@ contract('GeneralPermissionManager', accounts => { // STEP 7: Deploy the DummySTOFactory - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_DummySTOFactory.address.valueOf(), @@ -172,57 +176,61 @@ contract('GeneralPermissionManager', accounts => { "DummySTOFactory contract was not deployed" ); + // Step 8: Deploy the STFactory contract - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - // Step 9: Deploy the SecurityTokenRegistry contract + // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // STEP 8: Register the Modules with the ModuleRegistry contract + // STEP 8: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the Paid GeneralDelegateManagerFactory - await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the Paid GeneralDelegateManagerFactory + await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` @@ -243,11 +251,10 @@ contract('GeneralPermissionManager', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -255,43 +262,47 @@ contract('GeneralPermissionManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the General permission manager factory with the security token", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + await catchRevert( + I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }) + ); }); it("Should successfully attach the General permission manager factory with the security token", async () => { let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + const tx = await I_SecurityToken.addModule( + P_GeneralPermissionManagerFactory.address, + "0x", + web3.utils.toWei("500", "ether"), + 0, + { from: token_owner } + ); assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "GeneralPermissionManager", "GeneralPermissionManagerFactory module was not added" ); @@ -303,8 +314,7 @@ contract('GeneralPermissionManager', accounts => { const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "GeneralPermissionManager", "GeneralPermissionManagerFactory module was not added" ); @@ -312,87 +322,100 @@ contract('GeneralPermissionManager', accounts => { }); }); - describe("General Permission Manager test cases", async() => { - - it("Get the init data", async() => { + describe("General Permission Manager test cases", async () => { + it("Get the init data", async () => { let tx = await I_GeneralPermissionManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ""), 0); }); - it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async() => { - - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1})); + it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async () => { + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1 })); }); - it("Should fail to provide the permission-- because delegate is not yet added", async() => { - - await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner})); + it("Should fail to provide the permission-- because delegate is not yet added", async () => { + await catchRevert( + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { + from: token_owner + }) + ); }); - it("Should add the permission to the delegate", async() => { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); + it("Should add the permission to the delegate", async () => { + let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); assert.equal(tx.logs[0].args._delegate, account_delegate); }); - it("Should fail to provide the permission", async() => { - - await catchRevert(I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1})); + it("Should fail to provide the permission", async () => { + await catchRevert( + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { + from: account_investor1 + }) + ); }); - it("Should check the permission", async() => { - assert.isFalse(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); + it("Should check the permission", async () => { + assert.isFalse( + await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST") + ); }); - it("Should provide the permission", async() => { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); + it("Should provide the permission", async () => { + let tx = await I_GeneralPermissionManager.changePermission( + account_delegate, + I_GeneralTransferManager.address, + "WHITELIST", + true, + { from: token_owner } + ); assert.equal(tx.logs[0].args._delegate, account_delegate); }); - it("Should check the permission", async() => { - assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); + it("Should check the permission", async () => { + assert.isTrue( + await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST") + ); }); - it("Should check the delegate details", async() => { - assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)) - .replace(/\u0000/g, ''), - delegateDetails, - "Wrong delegate address get checked"); + it("Should check the delegate details", async () => { + assert.equal( + web3.utils.toAscii(await I_GeneralPermissionManager.getDelegateDetails.call(account_delegate)).replace(/\u0000/g, ""), + delegateDetails, + "Wrong delegate address get checked" + ); }); - it("Should get the permission of the general permission manager contract", async() => { + it("Should get the permission of the general permission manager contract", async () => { let tx = await I_GeneralPermissionManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]) - .replace(/\u0000/g, ''), - "CHANGE_PERMISSION", - "Wrong permissions"); + assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ""), "CHANGE_PERMISSION", "Wrong permissions"); }); }); - describe("General Permission Manager Factory test cases", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); - assert.equal((await I_GeneralPermissionManagerFactory.getTypes.call())[0],1); + describe("General Permission Manager Factory test cases", async () => { + it("should get the exact details of the factory", async () => { + assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(), 0); + assert.equal((await I_GeneralPermissionManagerFactory.getTypes.call())[0], 1); assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "GeneralPermissionManager", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getDescription.call(), - "Manage permissions within the Security Token and attached modules", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), - "General Permission Manager", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getInstructions.call(), - "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", - "Wrong Module added"); - + assert.equal( + web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()).replace(/\u0000/g, ""), + "GeneralPermissionManager", + "Wrong Module added" + ); + assert.equal( + await I_GeneralPermissionManagerFactory.getDescription.call(), + "Manage permissions within the Security Token and attached modules", + "Wrong Module added" + ); + assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), "General Permission Manager", "Wrong Module added"); + assert.equal( + await I_GeneralPermissionManagerFactory.getInstructions.call(), + "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", + "Wrong Module added" + ); }); - it("Should get the tags of the factory", async() => { + it("Should get the tags of the factory", async () => { let tags = await I_GeneralPermissionManagerFactory.getTags.call(); - assert.equal(tags.length,0); + assert.equal(tags.length, 0); }); }); - }); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index a971efa4f..a54976c8c 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -1,33 +1,32 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import {signData} from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); -const DummySTO = artifacts.require('./DummySTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('GeneralTransferManager', accounts => { - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { signData } from "./helpers/signData"; +import { pk } from "./helpers/testprivateKey"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); +const DummySTO = artifacts.require("./DummySTO.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("GeneralTransferManager", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -83,15 +82,15 @@ contract('GeneralTransferManager', accounts => { const initRegFee = web3.utils.toWei("250"); // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei("10", "ether"); const someString = "A string which is not used"; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STOParameters = ["uint256", "uint256", "uint256", "string"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -107,36 +106,33 @@ contract('GeneralTransferManager', accounts => { account_affiliates1 = accounts[3]; account_affiliates2 = accounts[4]; - // ----------- POLYMATH NETWORK Configuration ------------ + // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // STEP 2: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -146,7 +142,9 @@ contract('GeneralTransferManager', accounts => { // STEP 3: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -156,7 +154,7 @@ contract('GeneralTransferManager', accounts => { // STEP 4: Deploy the DummySTOFactory - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_DummySTOFactory.address.valueOf(), @@ -164,52 +162,57 @@ contract('GeneralTransferManager', accounts => { "DummySTOFactory contract was not deployed" ); - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + // Step 8: Deploy the STFactory contract - // Step 9: Deploy the SecurityTokenRegistry contract + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + // Step 9: Deploy the SecurityTokenRegistry contract - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` @@ -230,11 +233,10 @@ contract('GeneralTransferManager', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -249,51 +251,54 @@ contract('GeneralTransferManager', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - it("Should whitelist the affiliates before the STO attached", async() => { + it("Should whitelist the affiliates before the STO attached", async () => { let tx = await I_GeneralTransferManager.modifyWhitelistMulti( - [account_affiliates1, account_affiliates2], - [(latestTime() + duration.days(30)),(latestTime() + duration.days(30))], - [(latestTime() + duration.days(90)),(latestTime() + duration.days(90))], - [(latestTime() + duration.years(1)),(latestTime() + duration.years(1))], - [false, false], - { - from: account_issuer, - gas: 6000000 - }); + [account_affiliates1, account_affiliates2], + [latestTime() + duration.days(30), latestTime() + duration.days(30)], + [latestTime() + duration.days(90), latestTime() + duration.days(90)], + [latestTime() + duration.years(1), latestTime() + duration.years(1)], + [false, false], + { + from: account_issuer, + gas: 6000000 + } + ); assert.equal(tx.logs[0].args._investor, account_affiliates1); assert.equal(tx.logs[1].args._investor, account_affiliates2); }); it("Should mint the tokens to the affiliates", async () => { - await I_SecurityToken.mintMulti([account_affiliates1, account_affiliates2], [(100 * Math.pow(10, 18)), (100 * Math.pow(10, 18))], { from: account_issuer, gas:6000000 }); + await I_SecurityToken.mintMulti([account_affiliates1, account_affiliates2], [100 * Math.pow(10, 18), 100 * Math.pow(10, 18)], { + from: account_issuer, + gas: 6000000 + }); assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); }); it("Should successfully attach the STO factory with the security token", async () => { - let bytesSTO = encodeModuleCall(STOParameters, [latestTime() + duration.seconds(1000), latestTime() + duration.days(40), cap, someString]); + let bytesSTO = encodeModuleCall(STOParameters, [ + latestTime() + duration.seconds(1000), + latestTime() + duration.days(40), + cap, + someString + ]); const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), stoKey, "DummySTO doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "DummySTO", "DummySTOFactory module was not added" ); @@ -304,24 +309,20 @@ contract('GeneralTransferManager', accounts => { const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, 0, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "GeneralPermissionManager", "GeneralPermissionManager module was not added" ); I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); }); - }); - describe("Buy tokens using on-chain whitelist", async() => { - + describe("Buy tokens using on-chain whitelist", async () => { it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - - await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner })); }); - it("Should Buy the tokens", async() => { + it("Should Buy the tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -333,143 +334,183 @@ contract('GeneralTransferManager', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(5000); // Mint some tokens - await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Should fail in buying the token from the STO", async() => { - - await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei('1', 'ether'), { from: token_owner })); + it("Should fail in buying the token from the STO", async () => { + await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei("1", "ether"), { from: token_owner })); }); - it("Should fail in investing the money in STO -- expiry limit reached", async() => { - + it("Should fail in investing the money in STO -- expiry limit reached", async () => { await increaseTime(duration.days(10)); - await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner })); - }) - + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner })); + }); }); - describe("Buy tokens using off-chain whitelist", async() => { - + describe("Buy tokens using off-chain whitelist", async () => { it("Should buy the tokens -- Failed due to investor is not in the whitelist", async () => { - - await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner })); + await catchRevert(I_DummySTO.generateTokens(account_investor2, web3.utils.toWei("1", "ether"), { from: token_owner })); }); - it("Should buy the tokens -- Failed due to incorrect signature input", async() => { + it("Should buy the tokens -- Failed due to incorrect signature input", async () => { // Add the Investor in to the whitelist //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk let validFrom = latestTime(); let validTo = latestTime() + duration.days(5); - const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); + const sig = signData( + account_investor2, + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + token_owner_pk + ); - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; + const r = `0x${sig.r.toString("hex")}`; + const s = `0x${sig.s.toString("hex")}`; const v = sig.v; - - - await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - })); - - }); - - it("Should buy the tokens -- Failed due to incorrect signature timing", async() => { + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + } + ) + ); + }); + + it("Should buy the tokens -- Failed due to incorrect signature timing", async () => { // Add the Investor in to the whitelist //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk let validFrom = latestTime() - 100; - let validTo = latestTime() - 1; - const sig = signData(I_GeneralTransferManager.address, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, token_owner_pk); + let validTo = latestTime() - 1; + const sig = signData( + I_GeneralTransferManager.address, + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + token_owner_pk + ); - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; + const r = `0x${sig.r.toString("hex")}`; + const s = `0x${sig.s.toString("hex")}`; const v = sig.v; - - await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - })); - - }); - - it("Should buy the tokens -- Failed due to incorrect signature signer", async() => { + await catchRevert( + I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + } + ) + ); + }); + + it("Should buy the tokens -- Failed due to incorrect signature signer", async () => { // Add the Investor in to the whitelist //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk let validFrom = latestTime(); - let validTo = latestTime() + (60 * 60); + let validTo = latestTime() + 60 * 60; - const sig = signData(account_investor2, account_investor2, fromTime, toTime, expiryTime, true, validFrom, validTo, '2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200'); + const sig = signData( + account_investor2, + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + "2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200" + ); - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; + const r = `0x${sig.r.toString("hex")}`; + const s = `0x${sig.s.toString("hex")}`; const v = sig.v; - - - await catchRevert(I_GeneralTransferManager.modifyWhitelistSigned( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - validFrom, - validTo, - v, - r, - s, - { - from: account_investor2, - gas: 6000000 - })); - - }); - - it("Should Buy the tokens", async() => { + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistSigned( + account_investor2, + fromTime, + toTime, + expiryTime, + true, + validFrom, + validTo, + v, + r, + s, + { + from: account_investor2, + gas: 6000000 + } + ) + ); + }); + + it("Should Buy the tokens", async () => { // Add the Investor in to the whitelist //tmAddress, investorAddress, fromTime, toTime, validFrom, validTo, pk let validFrom = latestTime(); let validTo = latestTime() + duration.days(5); - const sig = signData(I_GeneralTransferManager.address, account_investor2, latestTime(), latestTime() + duration.days(80), expiryTime + duration.days(200), true, validFrom, validTo, token_owner_pk); + const sig = signData( + I_GeneralTransferManager.address, + account_investor2, + latestTime(), + latestTime() + duration.days(80), + expiryTime + duration.days(200), + true, + validFrom, + validTo, + token_owner_pk + ); - const r = `0x${sig.r.toString('hex')}`; - const s = `0x${sig.s.toString('hex')}`; + const r = `0x${sig.r.toString("hex")}`; + const s = `0x${sig.s.toString("hex")}`; const v = sig.v; let tx = await I_GeneralTransferManager.modifyWhitelistSigned( account_investor2, @@ -485,92 +526,91 @@ contract('GeneralTransferManager', accounts => { { from: account_investor2, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(10000); // Mint some tokens - await I_DummySTO.generateTokens(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); - - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + await I_DummySTO.generateTokens(account_investor2, web3.utils.toWei("1", "ether"), { from: token_owner }); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Should fail in changing the signing address", async() => { - - await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_investor4})); + it("Should fail in changing the signing address", async () => { + await catchRevert(I_GeneralTransferManager.changeSigningAddress(account_polymath, { from: account_investor4 })); }); - it("Should get the permission", async() => { + it("Should get the permission", async () => { let perm = await I_GeneralTransferManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), "WHITELIST"); - assert.equal(web3.utils.toAscii(perm[1]).replace(/\u0000/g, ''), "FLAGS"); + assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ""), "WHITELIST"); + assert.equal(web3.utils.toAscii(perm[1]).replace(/\u0000/g, ""), "FLAGS"); }); - it("Should provide the permission and change the signing address", async() => { - let log = await I_GeneralPermissionManager.addPermission(account_delegate, "My details", {from: token_owner}); + it("Should provide the permission and change the signing address", async () => { + let log = await I_GeneralPermissionManager.addPermission(account_delegate, "My details", { from: token_owner }); assert.equal(log.logs[0].args._delegate, account_delegate); - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FLAGS", true, {from: token_owner}); + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FLAGS", true, { + from: token_owner + }); - assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "FLAGS")); + assert.isTrue( + await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "FLAGS") + ); - let tx = await I_GeneralTransferManager.changeSigningAddress(account_polymath, {from: account_delegate}); + let tx = await I_GeneralTransferManager.changeSigningAddress(account_polymath, { from: account_delegate }); assert.equal(tx.logs[0].args._signingAddress, account_polymath); }); - it("Should fail to pull fees as no budget set", async() => { - - - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); + it("Should fail to pull fees as no budget set", async () => { + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: account_polymath })); }); - it("Should set a budget for the GeneralTransferManager", async() => { - await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), {from: token_owner}); - - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_polymath})); + it("Should set a budget for the GeneralTransferManager", async () => { + await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), { from: token_owner }); + + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: account_polymath })); await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); - await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), {from: token_owner}); + await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), { from: token_owner }); }); - - it("Factory owner should pull fees - fails as not permissioned by issuer", async() => { - - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate})); + it("Factory owner should pull fees - fails as not permissioned by issuer", async () => { + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: account_delegate })); }); - it("Should change the Issuance address", async() => { - let tx = await I_GeneralTransferManager.changeIssuanceAddress(account_investor2, {from: account_delegate}); + it("Should change the Issuance address", async () => { + let tx = await I_GeneralTransferManager.changeIssuanceAddress(account_investor2, { from: account_delegate }); assert.equal(tx.logs[0].args._issuanceAddress, account_investor2); }); - it("Should unpause the transfers", async() => { - await I_GeneralTransferManager.unpause({from: token_owner}); + it("Should unpause the transfers", async () => { + await I_GeneralTransferManager.unpause({ from: token_owner }); assert.isFalse(await I_GeneralTransferManager.paused.call()); }); - it("Should get the init function", async() => { + it("Should get the init function", async () => { let byte = await I_GeneralTransferManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); + assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ""), 0); }); - }); describe("WhiteList that addresses", async () => { - - it("Should fail in adding the investors in whitelist", async() => { + it("Should fail in adding the investors in whitelist", async () => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], [toTime, toTime], @@ -580,15 +620,17 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - )); + ) + ); }); - it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { + it("Should fail in adding the investors in whitelist -- array length mismatch", async () => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime], [toTime, toTime], @@ -598,15 +640,17 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - )); + ) + ); }); - it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { + it("Should fail in adding the investors in whitelist -- array length mismatch", async () => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], [toTime], @@ -616,15 +660,17 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - )); + ) + ); }); - it("Should fail in adding the investors in whitelist -- array length mismatch", async() => { + it("Should fail in adding the investors in whitelist -- array length mismatch", async () => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - - await catchRevert(I_GeneralTransferManager.modifyWhitelistMulti( + + await catchRevert( + I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], [toTime, toTime], @@ -634,14 +680,15 @@ contract('GeneralTransferManager', accounts => { from: account_delegate, gas: 6000000 } - )); + ) + ); }); - it("Should successfully add the investors in whitelist", async() => { + it("Should successfully add the investors in whitelist", async () => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(20); let expiryTime = toTime + duration.days(10); - + let tx = await I_GeneralTransferManager.modifyWhitelistMulti( [account_investor3, account_investor4], [fromTime, fromTime], @@ -657,77 +704,70 @@ contract('GeneralTransferManager', accounts => { }); }); - describe("General Transfer Manager Factory test cases", async() => { - - it("Should get the exact details of the factory", async() => { - assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(),0); - assert.equal((await I_GeneralTransferManagerFactory.getTypes.call())[0],2); - assert.equal(web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "GeneralTransferManager", - "Wrong Module added"); - assert.equal(await I_GeneralTransferManagerFactory.getDescription.call(), - "Manage transfers using a time based whitelist", - "Wrong Module added"); - assert.equal(await I_GeneralTransferManagerFactory.getTitle.call(), - "General Transfer Manager", - "Wrong Module added"); - assert.equal(await I_GeneralTransferManagerFactory.getInstructions.call(), - "Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters.", - "Wrong Module added"); - + describe("General Transfer Manager Factory test cases", async () => { + it("Should get the exact details of the factory", async () => { + assert.equal(await I_GeneralTransferManagerFactory.setupCost.call(), 0); + assert.equal((await I_GeneralTransferManagerFactory.getTypes.call())[0], 2); + assert.equal( + web3.utils.toAscii(await I_GeneralTransferManagerFactory.getName.call()).replace(/\u0000/g, ""), + "GeneralTransferManager", + "Wrong Module added" + ); + assert.equal( + await I_GeneralTransferManagerFactory.getDescription.call(), + "Manage transfers using a time based whitelist", + "Wrong Module added" + ); + assert.equal(await I_GeneralTransferManagerFactory.getTitle.call(), "General Transfer Manager", "Wrong Module added"); + assert.equal( + await I_GeneralTransferManagerFactory.getInstructions.call(), + "Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters.", + "Wrong Module added" + ); }); - it("Should get the tags of the factory", async() => { + it("Should get the tags of the factory", async () => { let tags = await I_GeneralTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "General"); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ""), "General"); }); }); - describe("Dummy STO Factory test cases", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_DummySTOFactory.setupCost.call(),0); - assert.equal((await I_DummySTOFactory.getTypes.call())[0],3); - assert.equal(web3.utils.toAscii(await I_DummySTOFactory.getName.call()) - .replace(/\u0000/g, ''), - "DummySTO", - "Wrong Module added"); - assert.equal(await I_DummySTOFactory.getDescription.call(), - "Dummy STO", - "Wrong Module added"); - assert.equal(await I_DummySTOFactory.getTitle.call(), - "Dummy STO", - "Wrong Module added"); - assert.equal(await I_DummySTOFactory.getInstructions.call(), - "Dummy STO - you can mint tokens at will", - "Wrong Module added"); - - }); - - it("Should get the tags of the factory", async() => { + describe("Dummy STO Factory test cases", async () => { + it("should get the exact details of the factory", async () => { + assert.equal(await I_DummySTOFactory.setupCost.call(), 0); + assert.equal((await I_DummySTOFactory.getTypes.call())[0], 3); + assert.equal( + web3.utils.toAscii(await I_DummySTOFactory.getName.call()).replace(/\u0000/g, ""), + "DummySTO", + "Wrong Module added" + ); + assert.equal(await I_DummySTOFactory.getDescription.call(), "Dummy STO", "Wrong Module added"); + assert.equal(await I_DummySTOFactory.getTitle.call(), "Dummy STO", "Wrong Module added"); + assert.equal(await I_DummySTOFactory.getInstructions.call(), "Dummy STO - you can mint tokens at will", "Wrong Module added"); + }); + + it("Should get the tags of the factory", async () => { let tags = await I_DummySTOFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "Dummy"); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ""), "Dummy"); }); }); - describe("Test cases for the get functions of the dummy sto", async() => { - - it("Should get the raised amount of ether", async() => { - assert.equal(await I_DummySTO.getRaised.call(0), web3.utils.toWei('0','ether')); + describe("Test cases for the get functions of the dummy sto", async () => { + it("Should get the raised amount of ether", async () => { + assert.equal(await I_DummySTO.getRaised.call(0), web3.utils.toWei("0", "ether")); }); - it("Should get the raised amount of poly", async() => { - assert.equal((await I_DummySTO.getRaised.call(1)).toNumber(), web3.utils.toWei('0','ether')); + it("Should get the raised amount of poly", async () => { + assert.equal((await I_DummySTO.getRaised.call(1)).toNumber(), web3.utils.toWei("0", "ether")); }); - it("Should get the investors", async() => { - assert.equal((await I_DummySTO.investorCount.call()).toNumber(), 2); + it("Should get the investors", async () => { + assert.equal((await I_DummySTO.investorCount.call()).toNumber(), 2); }); - it("Should get the listed permissions", async() => { - let tx = await I_DummySTO.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ''), "ADMIN"); + it("Should get the listed permissions", async () => { + let tx = await I_DummySTO.getPermissions.call(); + assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ""), "ADMIN"); }); }); - }); diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 9369f3eba..0092b51d1 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -1,42 +1,42 @@ -import { encodeProxyCall, encodeModuleCall } from './encodeCall'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryMock = artifacts.require('./SecurityTokenRegistryMock.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); -const STFactory = artifacts.require('./STFactory.sol'); -const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const PolyToken = artifacts.require('./PolyToken.sol'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - - // Contract Instance Declaration - let I_GeneralTransferManagerFactory; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_SecurityToken; - let I_PolyToken; - let I_STFactory; - let I_PolymathRegistry; - let I_SecurityTokenRegistryProxy; - let I_STRProxied; - let I_MRProxied; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; +import { encodeProxyCall, encodeModuleCall } from "./encodeCall"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); +const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); +const STFactory = artifacts.require("./STFactory.sol"); +const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const PolyToken = artifacts.require("./PolyToken.sol"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +// Contract Instance Declaration +let I_GeneralTransferManagerFactory; +let I_GeneralTransferManager; +let I_ModuleRegistryProxy; +let I_ModuleRegistry; +let I_FeatureRegistry; +let I_SecurityTokenRegistry; +let I_SecurityToken; +let I_PolyToken; +let I_STFactory; +let I_PolymathRegistry; +let I_SecurityTokenRegistryProxy; +let I_STRProxied; +let I_MRProxied; + +// Initial fee for ticker registry and security token registry +const initRegFee = web3.utils.toWei("250"); + +const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; +const MRProxyParameters = ["address", "address"]; export async function setUpPolymathNetwork(account_polymath, token_owner) { // ----------- POLYMATH NETWORK Configuration ------------ @@ -58,10 +58,8 @@ export async function setUpPolymathNetwork(account_polymath, token_owner) { await registerGTM(account_polymath); let tempArray = new Array(a, b, c, d, e, f); return mergeReturn(tempArray); - } - function mergeReturn(returnData) { let returnArray = new Array(); for (let i = 0; i < returnData.length; i++) { @@ -70,39 +68,33 @@ function mergeReturn(returnData) { } } return returnArray; - } - async function deployPolyRegistryAndPolyToken(account_polymath, token_owner) { // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); return new Array(I_PolymathRegistry, I_PolyToken); } async function deployFeatureRegistry(account_polymath) { + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - return new Array(I_FeatureRegistry) + return new Array(I_FeatureRegistry); } async function deployModuleRegistry(account_polymath) { - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); return new Array(I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied); @@ -121,44 +113,46 @@ async function deployGTM(account_polymath) { } async function deploySTFactory(account_polymath) { + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); return new Array(I_STFactory); } async function deploySTR(account_polymath) { - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // Step 9 (a): Deploy the proxy - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 9 (a): Deploy the proxy + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); + I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); return new Array(I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied); } async function setInPolymathRegistry(account_polymath) { - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); } - + async function registerGTM(account_polymath) { await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); diff --git a/test/helpers/encodeCall.js b/test/helpers/encodeCall.js index 6a48f12a1..7aaa9bbf8 100644 --- a/test/helpers/encodeCall.js +++ b/test/helpers/encodeCall.js @@ -1,14 +1,13 @@ -const abi = require('ethereumjs-abi') +const abi = require("ethereumjs-abi"); export function encodeProxyCall(parametersType, values) { - const methodId = abi.methodID("initialize", parametersType).toString('hex'); - const params = abi.rawEncode(parametersType, values).toString('hex'); - return '0x' + methodId + params; + const methodId = abi.methodID("initialize", parametersType).toString("hex"); + const params = abi.rawEncode(parametersType, values).toString("hex"); + return "0x" + methodId + params; } - export function encodeModuleCall(parametersType, values) { - const methodId = abi.methodID("configure", parametersType).toString('hex'); - const params = abi.rawEncode(parametersType, values).toString('hex'); - return '0x' + methodId + params; -} \ No newline at end of file + const methodId = abi.methodID("configure", parametersType).toString("hex"); + const params = abi.rawEncode(parametersType, values).toString("hex"); + return "0x" + methodId + params; +} diff --git a/test/helpers/exceptions.js b/test/helpers/exceptions.js index bdeda1472..22c05be07 100644 --- a/test/helpers/exceptions.js +++ b/test/helpers/exceptions.js @@ -1,56 +1,46 @@ -const PREFIX = 'VM Exception while processing transaction: '; -const PREFIX2 = 'Returned error: VM Exception while processing transaction: '; +const PREFIX = "VM Exception while processing transaction: "; +const PREFIX2 = "Returned error: VM Exception while processing transaction: "; async function tryCatch(promise, message) { - try { - await promise; - throw null; - } catch (error) { - assert(error, 'Expected an error but did not get one'); try { - assert( - error.message.startsWith(PREFIX + message), - "Expected an error starting with '" + - PREFIX + - message + - "' but got '" + - error.message + - "' instead" - ); - } catch (err) { - assert( - error.message.startsWith(PREFIX2 + message), - "Expected an error starting with '" + - PREFIX + - message + - "' but got '" + - error.message + - "' instead" - ); + await promise; + throw null; + } catch (error) { + assert(error, "Expected an error but did not get one"); + try { + assert( + error.message.startsWith(PREFIX + message), + "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead" + ); + } catch (err) { + assert( + error.message.startsWith(PREFIX2 + message), + "Expected an error starting with '" + PREFIX + message + "' but got '" + error.message + "' instead" + ); + } } - } } module.exports = { - catchRevert: async function(promise) { - await tryCatch(promise, 'revert'); - }, - catchOutOfGas: async function(promise) { - await tryCatch(promise, 'out of gas'); - }, - catchInvalidJump: async function(promise) { - await tryCatch(promise, 'invalid JUMP'); - }, - catchInvalidOpcode: async function(promise) { - await tryCatch(promise, 'invalid opcode'); - }, - catchStackOverflow: async function(promise) { - await tryCatch(promise, 'stack overflow'); - }, - catchStackUnderflow: async function(promise) { - await tryCatch(promise, 'stack underflow'); - }, - catchStaticStateChange: async function(promise) { - await tryCatch(promise, 'static state change'); - } -}; \ No newline at end of file + catchRevert: async function(promise) { + await tryCatch(promise, "revert"); + }, + catchOutOfGas: async function(promise) { + await tryCatch(promise, "out of gas"); + }, + catchInvalidJump: async function(promise) { + await tryCatch(promise, "invalid JUMP"); + }, + catchInvalidOpcode: async function(promise) { + await tryCatch(promise, "invalid opcode"); + }, + catchStackOverflow: async function(promise) { + await tryCatch(promise, "stack overflow"); + }, + catchStackUnderflow: async function(promise) { + await tryCatch(promise, "stack underflow"); + }, + catchStaticStateChange: async function(promise) { + await tryCatch(promise, "static state change"); + } +}; diff --git a/test/helpers/latestTime.js b/test/helpers/latestTime.js index 5e39a0355..38c744969 100644 --- a/test/helpers/latestTime.js +++ b/test/helpers/latestTime.js @@ -1,5 +1,4 @@ // Returns the time of the last mined block in seconds -export default function latestTime () { - return web3.eth.getBlock('latest').timestamp; - } - \ No newline at end of file +export default function latestTime() { + return web3.eth.getBlock("latest").timestamp; +} diff --git a/test/helpers/signData.js b/test/helpers/signData.js index 62b040719..9d8b33380 100644 --- a/test/helpers/signData.js +++ b/test/helpers/signData.js @@ -1,23 +1,21 @@ -const ethers = require('ethers'); +const ethers = require("ethers"); const utils = ethers.utils; -const ethUtil = require('ethereumjs-util'); +const ethUtil = require("ethereumjs-util"); //this, _investor, _fromTime, _toTime, _validTo function signData(tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo, pk) { - let packedData = utils.solidityKeccak256( - [ "address", "address", "uint256", "uint256", "uint256", "bool", "uint256", "uint256" ], - [ tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo ] - ).slice(2); - packedData = new Buffer(packedData, 'hex'); - packedData = Buffer.concat([ - new Buffer(`\x19Ethereum Signed Message:\n${packedData.length.toString()}`), - packedData]); - packedData = web3.sha3(`0x${packedData.toString('hex')}`, { encoding: 'hex' }); - return ethUtil.ecsign( - new Buffer(packedData.slice(2), 'hex'), - new Buffer(pk, 'hex')); + let packedData = utils + .solidityKeccak256( + ["address", "address", "uint256", "uint256", "uint256", "bool", "uint256", "uint256"], + [tmAddress, investorAddress, fromTime, toTime, expiryTime, restricted, validFrom, validTo] + ) + .slice(2); + packedData = new Buffer(packedData, "hex"); + packedData = Buffer.concat([new Buffer(`\x19Ethereum Signed Message:\n${packedData.length.toString()}`), packedData]); + packedData = web3.sha3(`0x${packedData.toString("hex")}`, { encoding: "hex" }); + return ethUtil.ecsign(new Buffer(packedData.slice(2), "hex"), new Buffer(pk, "hex")); } module.exports = { - signData -} + signData +}; diff --git a/test/helpers/testprivateKey.js b/test/helpers/testprivateKey.js index 16e464cd1..5808a712e 100644 --- a/test/helpers/testprivateKey.js +++ b/test/helpers/testprivateKey.js @@ -1,6 +1,6 @@ export const pk = { - account_0 :'2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200', - account_1 :'2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201' -} + account_0: "2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200", + account_1: "2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201" +}; export default { pk }; diff --git a/test/helpers/time.js b/test/helpers/time.js index 37533c92b..3e3362d81 100644 --- a/test/helpers/time.js +++ b/test/helpers/time.js @@ -2,61 +2,73 @@ // aren’t included within the original RPC specification. // See https://github.com/ethereumjs/testrpc#implemented-methods -function increaseTime (duration) { +function increaseTime(duration) { const id = Date.now(); - + return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_increaseTime', - params: [duration], - id: id, - }, err1 => { - if (err1) return reject(err1); - - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_mine', - id: id + 1, - }, (err2, res) => { - return err2 ? reject(err2) : resolve(res); - }); - }); + web3.currentProvider.sendAsync( + { + jsonrpc: "2.0", + method: "evm_increaseTime", + params: [duration], + id: id + }, + err1 => { + if (err1) return reject(err1); + + web3.currentProvider.sendAsync( + { + jsonrpc: "2.0", + method: "evm_mine", + id: id + 1 + }, + (err2, res) => { + return err2 ? reject(err2) : resolve(res); + } + ); + } + ); }); - } +} export default function takeSnapshot() { return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_snapshot', - params: [], - id: new Date().getTime() - }, (err, result) => { - if (err) { - return reject(err); - } + web3.currentProvider.sendAsync( + { + jsonrpc: "2.0", + method: "evm_snapshot", + params: [], + id: new Date().getTime() + }, + (err, result) => { + if (err) { + return reject(err); + } - resolve(result.result); - }); + resolve(result.result); + } + ); }); -}; +} function revertToSnapshot(snapShotId) { return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'evm_revert', - params: [snapShotId], - id: new Date().getTime() - }, (err) => { - if (err) { - return reject(err); - } + web3.currentProvider.sendAsync( + { + jsonrpc: "2.0", + method: "evm_revert", + params: [snapShotId], + id: new Date().getTime() + }, + err => { + if (err) { + return reject(err); + } - resolve(); - }); + resolve(); + } + ); }); -}; +} - export { increaseTime, takeSnapshot, revertToSnapshot }; \ No newline at end of file +export { increaseTime, takeSnapshot, revertToSnapshot }; diff --git a/test/helpers/utils.js b/test/helpers/utils.js index c1c900de1..a2c23c218 100644 --- a/test/helpers/utils.js +++ b/test/helpers/utils.js @@ -4,63 +4,70 @@ var _ = require("lodash"); function isException(error) { let strError = error.toString(); - return strError.includes('invalid opcode') || strError.includes('invalid JUMP') || strError.includes('revert'); + return strError.includes("invalid opcode") || strError.includes("invalid JUMP") || strError.includes("revert"); } function ensureException(error) { assert(isException(error), error.toString()); } -async function timeDifference(timestamp1,timestamp2) { +async function timeDifference(timestamp1, timestamp2) { var difference = timestamp1 - timestamp2; return difference; } function convertHex(hexx) { var hex = hexx.toString(); //force conversion - var str = ''; + var str = ""; for (var i = 0; i < hex.length; i += 2) { - let char = String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - if (char != '\u0000') str += char; + let char = String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + if (char != "\u0000") str += char; } return str; - } +} -export { - ensureException, - timeDifference, - convertHex } +export { ensureException, timeDifference, convertHex }; export const duration = { - seconds: function (val) { return val; }, - minutes: function (val) { return val * this.seconds(60); }, - hours: function (val) { return val * this.minutes(60); }, - days: function (val) { return val * this.hours(24); }, - weeks: function (val) { return val * this.days(7); }, - years: function (val) { return val * this.days(365); }, - }; - + seconds: function(val) { + return val; + }, + minutes: function(val) { + return val * this.seconds(60); + }, + hours: function(val) { + return val * this.minutes(60); + }, + days: function(val) { + return val * this.hours(24); + }, + weeks: function(val) { + return val * this.days(7); + }, + years: function(val) { + return val * this.days(365); + } +}; /** -* Helper to wait for log emission. -* @param {Object} _event The event to wait for. -*/ + * Helper to wait for log emission. + * @param {Object} _event The event to wait for. + */ export function promisifyLogWatch(_event, _times) { - return new Promise((resolve, reject) => { - let i = 0; - _event.watch((error, log) => { - if (error !== null) - reject(error); - i = i + 1; - console.log("Received event: " + i + " out of: " + _times); - if (i == _times) { - _event.stopWatching(); - resolve(log); - } - }); - }); - } + return new Promise((resolve, reject) => { + let i = 0; + _event.watch((error, log) => { + if (error !== null) reject(error); + i = i + 1; + console.log("Received event: " + i + " out of: " + _times); + if (i == _times) { + _event.stopWatching(); + resolve(log); + } + }); + }); +} - export function latestBlock () { - return web3.eth.getBlock('latest').number; - } \ No newline at end of file +export function latestBlock() { + return web3.eth.getBlock("latest").number; +} diff --git a/test/i_Issuance.js b/test/i_Issuance.js index a9c502252..10c80b1db 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -1,32 +1,29 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); -const CappedSTO = artifacts.require('./CappedSTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - - -contract('Issuance', accounts => { - - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); +const CappedSTO = artifacts.require("./CappedSTO.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("Issuance", accounts => { // Accounts Variable declaration let account_polymath; let account_investor1; @@ -39,7 +36,7 @@ contract('Issuance', accounts => { let balanceOfReceiver; let message = "Transaction Should Fail!"; const TM_Perm = "WHITELIST"; - const delegateDetails = "I am delegate" + const delegateDetails = "I am delegate"; // investor Details let fromTime = latestTime(); let toTime = latestTime() + duration.days(15); @@ -85,14 +82,13 @@ contract('Issuance', accounts => { const cap = web3.utils.toWei("10000"); const rate = 1000; const fundRaiseType = [0]; - const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); + const cappedSTOSetupCost = web3.utils.toWei("20000", "ether"); const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - + const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -105,32 +101,30 @@ contract('Issuance', accounts => { // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -140,7 +134,9 @@ contract('Issuance', accounts => { // STEP 5: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -160,36 +156,41 @@ contract('Issuance', accounts => { // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // STEP 7: Register the Modules with the ModuleRegistry contract @@ -224,14 +225,12 @@ contract('Issuance', accounts => { `); }); - describe("Launch SecurityToken & STO on the behalf of the issuer", async() => { - - describe("Create securityToken for the issuer by the polymath", async() => { - + describe("Launch SecurityToken & STO on the behalf of the issuer", async () => { + describe("Create securityToken for the issuer by the polymath", async () => { it("POLYMATH: Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_polymath); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_polymath); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); - let tx = await I_STRProxied.registerTicker(account_polymath, symbol, name, { from : account_polymath }); + let tx = await I_STRProxied.registerTicker(account_polymath, symbol, name, { from: account_polymath }); assert.equal(tx.logs[0].args._owner, account_polymath); assert.equal(tx.logs[0].args._ticker, symbol); }); @@ -240,33 +239,27 @@ contract('Issuance', accounts => { console.log(name, symbol, tokenDetails, false); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_polymath }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_polymath }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("POLYMATH: Should intialize the auto attached modules", async () => { let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); - - }); - - it("POLYMATH: Should successfully attach the STO factory with the security token", async () => { - // STEP 4: Deploy the CappedSTOFactory + it("POLYMATH: Should successfully attach the STO factory with the security token", async () => { + // STEP 4: Deploy the CappedSTOFactory I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: account_polymath }); @@ -280,17 +273,23 @@ contract('Issuance', accounts => { await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - let bytesSTO = encodeModuleCall(STOParameters, [(latestTime() + duration.seconds(5000)), (latestTime() + duration.days(30)), cap, rate, fundRaiseType, account_fundsReceiver]); + let bytesSTO = encodeModuleCall(STOParameters, [ + latestTime() + duration.seconds(5000), + latestTime() + duration.days(30), + cap, + rate, + fundRaiseType, + account_fundsReceiver + ]); await I_PolyToken.getTokens(cappedSTOSetupCost, account_polymath); - await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: account_polymath}); + await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: account_polymath }); const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: account_polymath }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "CappedSTO", "CappedSTOFactory module was not added" ); @@ -298,9 +297,8 @@ contract('Issuance', accounts => { }); }); - describe("Transfer Manager operations by the polymath_account", async() => { + describe("Transfer Manager operations by the polymath_account", async () => { it("Should modify the whitelist", async () => { - fromTime = latestTime(); toTime = latestTime() + duration.days(15); expiryTime = toTime + duration.days(100); @@ -313,32 +311,37 @@ contract('Issuance', accounts => { true, { from: account_polymath - }); + } + ); assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); }); - it("Should add the delegate with permission", async() => { - //First attach a permission manager to the token - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: account_polymath}); - let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; - I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath}); - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: account_polymath }); - - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); + it("Should add the delegate with permission", async () => { + //First attach a permission manager to the token + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, { from: account_polymath }); + let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; + I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); + // Add permission to the deletgate (A regesteration process) + await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_polymath }); + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { + from: account_polymath + }); + + assert.isTrue( + await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm) + ); }); - it("POLYMATH: Should change the ownership of the SecurityToken", async() => { - await I_SecurityToken.transferOwnership(token_owner, { from : account_polymath }); + it("POLYMATH: Should change the ownership of the SecurityToken", async () => { + await I_SecurityToken.transferOwnership(token_owner, { from: account_polymath }); assert.equal(await I_SecurityToken.owner.call(), token_owner); }); - }) + }); - describe("Operations on the STO", async() => { - it("Should Buy the tokens", async() => { + describe("Operations on the STO", async () => { + it("Should Buy the tokens", async () => { balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); blockNo = latestBlock(); // Jump time @@ -348,49 +351,27 @@ contract('Issuance', accounts => { from: account_investor1, to: I_CappedSTO.address, gas: 6100000, - value: web3.utils.toWei('1', 'ether') - }); + value: web3.utils.toWei("1", "ether") + }); - assert.equal( - (await I_CappedSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); + assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); assert.equal(await I_CappedSTO.investorCount.call(), 1); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); }); - it("Verification of the event Token Purchase", async() => { - const log = await promisifyLogWatch(I_CappedSTO.TokenPurchase({from: blockNo}), 1); + it("Verification of the event Token Purchase", async () => { + const log = await promisifyLogWatch(I_CappedSTO.TokenPurchase({ from: blockNo }), 1); assert.equal(log.args.purchaser, account_investor1, "Wrong address of the investor"); - assert.equal( - (log.args.amount) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000, - "Wrong No. token get dilivered" - ); + assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000, "Wrong No. token get dilivered"); }); it("should add the investor into the whitelist by the delegate", async () => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - { - from: account_delegate, - gas: 7000000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { + from: account_delegate, + gas: 7000000 + }); assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); }); @@ -399,25 +380,15 @@ contract('Issuance', accounts => { from: account_investor2, to: I_CappedSTO.address, gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); + value: web3.utils.toWei("1", "ether") + }); - assert.equal( - (await I_CappedSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 2 - ); + assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2); assert.equal(await I_CappedSTO.investorCount.call(), 2); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }) + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); }); }); }); diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 431fbf404..5276d1468 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -1,33 +1,32 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const ManualApprovalTransferManagerFactory = artifacts.require('./ManualApprovalTransferManagerFactory.sol'); -const ManualApprovalTransferManager = artifacts.require('./ManualApprovalTransferManager'); -const CountTransferManagerFactory = artifacts.require('./CountTransferManagerFactory.sol'); -const CountTransferManager = artifacts.require('./CountTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('ManualApprovalTransferManager', accounts => { - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); +const ManualApprovalTransferManager = artifacts.require("./ManualApprovalTransferManager"); +const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); +const CountTransferManager = artifacts.require("./CountTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("ManualApprovalTransferManager", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -83,11 +82,11 @@ contract('ManualApprovalTransferManager', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -103,32 +102,30 @@ contract('ManualApprovalTransferManager', accounts => { // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -138,7 +135,9 @@ contract('ManualApprovalTransferManager', accounts => { // STEP 5: Deploy the GeneralDelegateManagerFactoryFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -147,7 +146,9 @@ contract('ManualApprovalTransferManager', accounts => { ); // STEP 6: Deploy the ManualApprovalTransferManagerFactory - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_ManualApprovalTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -155,7 +156,13 @@ contract('ManualApprovalTransferManager', accounts => { ); // STEP 7: Deploy the Paid ManualApprovalTransferManagerFactory - P_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); + P_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new( + I_PolyToken.address, + web3.utils.toWei("500", "ether"), + 0, + 0, + { from: account_polymath } + ); assert.notEqual( P_ManualApprovalTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -163,7 +170,7 @@ contract('ManualApprovalTransferManager', accounts => { ); // STEP 8: Deploy the CountTransferManagerFactory - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_CountTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -172,36 +179,41 @@ contract('ManualApprovalTransferManager', accounts => { // Step 10: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // Step 11: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); // Step 12: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); // Step 13: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // STEP 9: Register the Modules with the ModuleRegistry contract @@ -244,11 +256,10 @@ contract('ManualApprovalTransferManager', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -256,14 +267,14 @@ contract('ManualApprovalTransferManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); @@ -271,16 +282,13 @@ contract('ManualApprovalTransferManager', accounts => { }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - }); - describe("Buy tokens using whitelist & manual approvals", async() => { - - it("Should Buy the tokens", async() => { + describe("Buy tokens using whitelist & manual approvals", async () => { + it("Should Buy the tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -292,23 +300,25 @@ contract('ManualApprovalTransferManager', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(5000); // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('4', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("4", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('4', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("4", "ether")); }); - it("Should Buy some more tokens", async() => { + it("Should Buy some more tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -320,33 +330,43 @@ contract('ManualApprovalTransferManager', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("1", "ether")); }); it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + await catchRevert( + I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }) + ); }); it("Should successfully attach the General permission manager factory with the security token", async () => { let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + const tx = await I_SecurityToken.addModule( + P_ManualApprovalTransferManagerFactory.address, + "0x", + web3.utils.toWei("500", "ether"), + 0, + { from: token_owner } + ); assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "ManualApprovalTransferManager", "ManualApprovalTransferManagerFactory module was not added" ); @@ -354,24 +374,42 @@ contract('ManualApprovalTransferManager', accounts => { await revertToSnapshot(snapId); }); - it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); - assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManager module was not added"); + assert.equal( + web3.utils.toUtf8(tx.logs[2].args._name), + "ManualApprovalTransferManager", + "ManualApprovalTransferManager module was not added" + ); I_ManualApprovalTransferManager = ManualApprovalTransferManager.at(tx.logs[2].args._module); }); -//function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { - it("Cannot call verifyTransfer on the TM directly if _isTransfer == true", async() => { - await catchRevert(I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), "", true, { from: token_owner })); + //function verifyTransfer(address _from, address _to, uint256 _amount, bool _isTransfer) public returns(Result) { + it("Cannot call verifyTransfer on the TM directly if _isTransfer == true", async () => { + await catchRevert( + I_ManualApprovalTransferManager.verifyTransfer( + account_investor4, + account_investor4, + web3.utils.toWei("2", "ether"), + "", + true, + { from: token_owner } + ) + ); }); - it("Can call verifyTransfer on the TM directly if _isTransfer == false", async() => { - await I_ManualApprovalTransferManager.verifyTransfer(account_investor4, account_investor4, web3.utils.toWei('2', 'ether'), "", false, { from: token_owner }); + it("Can call verifyTransfer on the TM directly if _isTransfer == false", async () => { + await I_ManualApprovalTransferManager.verifyTransfer( + account_investor4, + account_investor4, + web3.utils.toWei("2", "ether"), + "", + false, + { from: token_owner } + ); }); - it("Add a new token holder", async() => { - + it("Add a new token holder", async () => { let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor3, latestTime(), @@ -381,187 +419,222 @@ contract('ManualApprovalTransferManager', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor3.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor3, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Should still be able to transfer between existing token holders", async() => { + it("Should still be able to transfer between existing token holders", async () => { // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("1", "ether"), { from: account_investor2 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('5', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("5", "ether")); }); - it("Should fail to add a manual approval because invalid _from address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualApproval("", account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); + it("Should fail to add a manual approval because invalid _from address", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualApproval( + "", + account_investor4, + web3.utils.toWei("2", "ether"), + latestTime() + duration.days(1), + { from: token_owner } + ) + ); }); - it("Should fail to add a manual approval because invalid _to address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, "", web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner })); + it("Should fail to add a manual approval because invalid _to address", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + "", + web3.utils.toWei("2", "ether"), + latestTime() + duration.days(1), + { from: token_owner } + ) + ); }); - it("Should fail to add a manual approval because invalid expiry time", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { from: token_owner })); + it("Should fail to add a manual approval because invalid expiry time", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + account_investor4, + web3.utils.toWei("2", "ether"), + 99999, + { from: token_owner } + ) + ); }); - it("Add a manual approval for a 4th investor", async() => { - await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + it("Add a manual approval for a 4th investor", async () => { + await I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + account_investor4, + web3.utils.toWei("2", "ether"), + latestTime() + duration.days(1), + { from: token_owner } + ); }); - it("Should fail to revoke manual approval because invalid _from address", async() => { - + it("Should fail to revoke manual approval because invalid _from address", async () => { await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner })); }); - it("Should fail to revoke manual approval because invalid _to address", async() => { - + it("Should fail to revoke manual approval because invalid _to address", async () => { await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, "", { from: token_owner })); }); - it("Should revoke manual approval", async() => { - let tx = await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, account_investor4, { from: token_owner }); + it("Should revoke manual approval", async () => { + let tx = await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, account_investor4, { + from: token_owner + }); assert.equal(tx.logs[0].args._from, account_investor1); assert.equal(tx.logs[0].args._to, account_investor4); assert.equal(tx.logs[0].args._addedBy, token_owner); - await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + await I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + account_investor4, + web3.utils.toWei("2", "ether"), + latestTime() + duration.days(1), + { from: token_owner } + ); }); - it("Use 50% of manual approval for transfer", async() => { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + it("Use 50% of manual approval for transfer", async () => { + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei("1", "ether"), { from: account_investor1 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor4)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor4)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Check verifyTransfer without actually transferring", async() => { - let verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether'), ""); + it("Check verifyTransfer without actually transferring", async () => { + let verified = await I_SecurityToken.verifyTransfer.call( + account_investor1, + account_investor4, + web3.utils.toWei("1", "ether"), + "" + ); console.log(JSON.stringify(verified)); assert.equal(verified, true); - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), ""); + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei("2", "ether"), ""); assert.equal(verified, false); - verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei('1', 'ether'), ""); + verified = await I_SecurityToken.verifyTransfer.call(account_investor1, account_investor4, web3.utils.toWei("1", "ether"), ""); assert.equal(verified, true); - }); - it("Use remaining 50% of manual approval for transfer", async() => { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + it("Use remaining 50% of manual approval for transfer", async () => { + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei("1", "ether"), { from: account_investor1 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor4)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor4)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Check further transfers fail", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); + it("Check further transfers fail", async () => { + await catchRevert(I_SecurityToken.transfer(account_investor4, web3.utils.toWei("1", "ether"), { from: account_investor1 })); //Check that other transfers are still valid - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 }); }); - it("Should fail to add a manual block because invalid _from address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { from: token_owner })); + it("Should fail to add a manual block because invalid _from address", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { + from: token_owner + }) + ); }); - it("Should fail to add a manual block because invalid _to address", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { from: token_owner })); + it("Should fail to add a manual block because invalid _to address", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { + from: token_owner + }) + ); }); - it("Should fail to add a manual block because invalid expiry time", async() => { - - await catchRevert(I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner })); + it("Should fail to add a manual block because invalid expiry time", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner }) + ); }); - it("Add a manual block for a 2nd investor", async() => { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); + it("Add a manual block for a 2nd investor", async () => { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { + from: token_owner + }); }); - it("Check manual block causes failure", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - + it("Check manual block causes failure", async () => { + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 })); }); - it("Should fail to revoke manual block because invalid _from address", async() => { - + it("Should fail to revoke manual block because invalid _from address", async () => { await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking("0x0", account_investor2, { from: token_owner })); }); - it("Should fail to revoke manual block because invalid _to address", async() => { - + it("Should fail to revoke manual block because invalid _to address", async () => { await catchRevert(I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, "0x0", { from: token_owner })); }); - it("Revoke manual block and check transfer works", async() => { + it("Revoke manual block and check transfer works", async () => { await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, account_investor2, { from: token_owner }); - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 }); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Check manual block ignored after expiry", async() => { - await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); - - await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 })); - await increaseTime(1 + (24 * 60 * 60)); - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + it("Check manual block ignored after expiry", async () => { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { + from: token_owner + }); + + await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 })); + await increaseTime(1 + 24 * 60 * 60); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 }); }); it("Should successfully attach the CountTransferManager with the security token (count of 1)", async () => { - let bytesCountTM = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_maxHolderCount' - } - ] - }, [1]); + let bytesCountTM = web3.eth.abi.encodeFunctionCall( + { + name: "configure", + type: "function", + inputs: [ + { + type: "uint256", + name: "_maxHolderCount" + } + ] + }, + [1] + ); const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); let name = web3.utils.toUtf8(tx.logs[2].args._name); assert.equal(name, "CountTransferManager", "CountTransferManager module was not added"); I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); - }); - it("Should get the permission list", async() => { + it("Should get the permission list", async () => { let perm = await I_ManualApprovalTransferManager.getPermissions.call(); assert.equal(perm.length, 1); }); // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { // //Should fail initial transfer - // + // // try { // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); // } catch(error) { @@ -574,32 +647,33 @@ contract('ManualApprovalTransferManager', accounts => { // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); // }); - it("Should get the init function", async() => { - let byte = await I_ManualApprovalTransferManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ''), 0); - }); - + it("Should get the init function", async () => { + let byte = await I_ManualApprovalTransferManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ""), 0); + }); }); - describe("ManualApproval Transfer Manager Factory test cases", async() => { - - it("Should get the exact details of the factory", async() => { - assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(),0); - assert.equal((await I_ManualApprovalTransferManagerFactory.getTypes.call())[0],2); + describe("ManualApproval Transfer Manager Factory test cases", async () => { + it("Should get the exact details of the factory", async () => { + assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(), 0); + assert.equal((await I_ManualApprovalTransferManagerFactory.getTypes.call())[0], 2); let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); - assert.equal(name,"ManualApprovalTransferManager","Wrong Module added"); + assert.equal(name, "ManualApprovalTransferManager", "Wrong Module added"); let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); - assert.equal(desc,"Manage transfers using single approvals / blocking","Wrong Module added"); + assert.equal(desc, "Manage transfers using single approvals / blocking", "Wrong Module added"); let title = await I_ManualApprovalTransferManagerFactory.getTitle.call(); - assert.equal(title,"Manual Approval Transfer Manager","Wrong Module added"); + assert.equal(title, "Manual Approval Transfer Manager", "Wrong Module added"); let inst = await I_ManualApprovalTransferManagerFactory.getInstructions.call(); - assert.equal(inst,"Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.","Wrong Module added"); + assert.equal( + inst, + "Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.", + "Wrong Module added" + ); }); - it("Should get the tags of the factory", async() => { + it("Should get the tags of the factory", async () => { let tags = await I_ManualApprovalTransferManagerFactory.getTags.call(); assert.equal(web3.utils.toUtf8(tags[0]), "ManualApproval"); }); }); - }); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index a7f1aa774..76cc9faea 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -1,36 +1,33 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); -const CappedSTO = artifacts.require('./CappedSTO.sol'); -const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); -const MockFactory = artifacts.require('./MockFactory.sol'); -const TestSTOFactory = artifacts.require('./TestSTOFactory.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - - -contract('ModuleRegistry', accounts => { - - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); +const CappedSTO = artifacts.require("./CappedSTO.sol"); +const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); +const MockFactory = artifacts.require("./MockFactory.sol"); +const TestSTOFactory = artifacts.require("./TestSTOFactory.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("ModuleRegistry", accounts => { // Accounts Variable declaration let account_polymath; let account_investor1; @@ -89,7 +86,7 @@ contract('ModuleRegistry', accounts => { // delagate details const delegateDetails = "I am delegate .."; - const TM_Perm = 'FLAGS'; + const TM_Perm = "FLAGS"; // Capped STO details let startTime; @@ -97,11 +94,11 @@ contract('ModuleRegistry', accounts => { const cap = web3.utils.toWei("10000"); const rate = 1000; const fundRaiseType = [0]; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256','uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -114,40 +111,37 @@ contract('ModuleRegistry', accounts => { // ----------- POLYMATH NETWORK Configuration ------------ - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); - // STEP 3: Deploy the ModuleRegistry + // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); assert.notEqual( I_ModuleRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "ModuleRegistry contract was not deployed", + "ModuleRegistry contract was not deployed" ); - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - let tx = await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + let tx = await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // STEP 2: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -155,44 +149,47 @@ contract('ModuleRegistry', accounts => { "GeneralTransferManagerFactory contract was not deployed" ); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // Step 9: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - assert.notEqual( I_FeatureRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "FeatureRegistry contract was not deployed", + "FeatureRegistry contract was not deployed" ); // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // Printing all the contract addresses console.log(` @@ -210,56 +207,60 @@ contract('ModuleRegistry', accounts => { `); }); - describe("Test cases for the ModuleRegistry", async() => { - - describe("Test case for the upgradeFromregistry", async() => { - - it("Should successfully update the registry contract address -- failed because of bad owner", async() => { - - await catchRevert(I_MRProxied.updateFromRegistry({from: account_temp})); + describe("Test cases for the ModuleRegistry", async () => { + describe("Test case for the upgradeFromregistry", async () => { + it("Should successfully update the registry contract address -- failed because of bad owner", async () => { + await catchRevert(I_MRProxied.updateFromRegistry({ from: account_temp })); }); - it("Should successfully update the registry contract addresses", async() => { - await I_MRProxied.updateFromRegistry({from: account_polymath}); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("securityTokenRegistry")), I_SecurityTokenRegistryProxy.address); - assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("featureRegistry")), I_FeatureRegistry.address); + it("Should successfully update the registry contract addresses", async () => { + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + assert.equal( + await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("securityTokenRegistry")), + I_SecurityTokenRegistryProxy.address + ); + assert.equal( + await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("featureRegistry")), + I_FeatureRegistry.address + ); assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")), I_PolyToken.address); }); - }); - describe("Test the state variables", async() => { - - it("Should be the right owner", async() => { - let _owner = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3('owner')); + describe("Test the state variables", async () => { + it("Should be the right owner", async () => { + let _owner = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("owner")); assert.equal(_owner, account_polymath, "Owner should be the correct"); - }) + }); - it("Should be the expected value of the paused and intialised variable", async() => { + it("Should be the expected value of the paused and intialised variable", async () => { let _paused = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); assert.isFalse(_paused, "Should be the false"); let _intialised = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("initialised")); assert.isTrue(_intialised, "Values should be the true"); - }) + }); - it("Should be the expected value of the polymath registry", async() => { + it("Should be the expected value of the polymath registry", async () => { let _polymathRegistry = await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry")); - assert.equal(_polymathRegistry, I_PolymathRegistry.address, "Should be the right value of the address of the polymath registry"); + assert.equal( + _polymathRegistry, + I_PolymathRegistry.address, + "Should be the right value of the address of the polymath registry" + ); }); }); - describe("Test cases for the registering the module", async() => { + describe("Test cases for the registering the module", async () => { + it("Should fail to register the module -- when registerModule is paused", async () => { + await I_MRProxied.pause({ from: account_polymath }); - it("Should fail to register the module -- when registerModule is paused", async() => { - await I_MRProxied.pause({from: account_polymath}); - - await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_delegate})); - await I_MRProxied.unpause({from: account_polymath}); - }) + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_delegate })); + await I_MRProxied.unpause({ from: account_polymath }); + }); - it("Should register the module with the Module Registry", async() => { - let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath}); + it("Should register the module with the Module Registry", async () => { + let tx = await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, "Should be the same address"); assert.equal(tx.logs[0].args._owner, account_polymath, "Should be the right owner"); @@ -271,81 +272,60 @@ contract('ModuleRegistry', accounts => { assert.equal(_reputation.length, 0); }); - it("Should fail the register the module -- Already registered module", async() => { - - await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, {from: account_polymath})); - }) + it("Should fail the register the module -- Already registered module", async () => { + await catchRevert(I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath })); + }); + + it("Should fail in registering the module-- type = 0", async () => { + I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - it("Should fail in registering the module-- type = 0", async() => { - I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); }); }); - describe("Test case for verifyModule", async() => { - + describe("Test case for verifyModule", async () => { it("Should fail in calling the verify module. Because msg.sender should be account_polymath", async () => { - await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); }); - it("Should successfully verify the module -- true", async() => { + it("Should successfully verify the module -- true", async () => { let tx = await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - assert.equal( - tx.logs[0].args._moduleFactory, - I_GeneralTransferManagerFactory.address, - "Failed in verifying the module" - ); - assert.equal( - tx.logs[0].args._verified, - true, - "Failed in verifying the module" - ); + assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, "Failed in verifying the module"); + assert.equal(tx.logs[0].args._verified, true, "Failed in verifying the module"); }); - it("Should successfully verify the module -- false", async() => { - I_CappedSTOFactory1 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - await I_MRProxied.registerModule(I_CappedSTOFactory1.address, {from: account_polymath}); + it("Should successfully verify the module -- false", async () => { + I_CappedSTOFactory1 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + await I_MRProxied.registerModule(I_CappedSTOFactory1.address, { from: account_polymath }); let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory1.address, false, { from: account_polymath }); - assert.equal( - tx.logs[0].args._moduleFactory, - I_CappedSTOFactory1.address, - "Failed in verifying the module" - ); - assert.equal( - tx.logs[0].args._verified, - false, - "Failed in verifying the module" - ); + assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory1.address, "Failed in verifying the module"); + assert.equal(tx.logs[0].args._verified, false, "Failed in verifying the module"); }); - it("Should fail in verifying the module. Because the module is not registered", async() => { - + it("Should fail in verifying the module. Because the module is not registered", async () => { await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); }); - }) - - describe("Test cases for the useModule function of the module registry", async() => { + }); - it("Deploy the securityToken", async() => { + describe("Test cases for the useModule function of the module registry", async () => { + it("Deploy the securityToken", async () => { await I_PolyToken.getTokens(web3.utils.toWei("500"), account_issuer); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), {from: account_issuer}); - await I_STRProxied.registerTicker(account_issuer, symbol, name, {from: account_issuer}); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, {from: account_issuer}); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: account_issuer }); + await I_STRProxied.registerTicker(account_issuer, symbol, name, { from: account_issuer }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, { from: account_issuer }); assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase()); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); }); - it("Should fail in adding module. Because module is un-verified", async() => { + it("Should fail in adding module. Because module is un-verified", async () => { startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner})); + + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, 0, 0, { from: token_owner })); }); - it("Should fail to register module because custom modules not allowed", async() => { + it("Should fail to register module because custom modules not allowed", async () => { I_CappedSTOFactory2 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); assert.notEqual( @@ -354,29 +334,33 @@ contract('ModuleRegistry', accounts => { "CappedSTOFactory contract was not deployed" ); - - await catchRevert(I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner })); - }); - it("Should switch customModulesAllowed to true", async() => { - assert.equal(false, await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), "Custom modules should be dissabled by default."); + it("Should switch customModulesAllowed to true", async () => { + assert.equal( + false, + await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), + "Custom modules should be dissabled by default." + ); let tx = await I_FeatureRegistry.setFeatureStatus("customModulesAllowed", true, { from: account_polymath }); - assert.equal(true, await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), "Custom modules should be switched to true."); + assert.equal( + true, + await I_FeatureRegistry.getFeatureStatus.call("customModulesAllowed"), + "Custom modules should be switched to true." + ); }); - it("Should successfully add module because custom modules switched on", async() => { + it("Should successfully add module because custom modules switched on", async () => { startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); - tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner}); + tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "CappedSTO", "CappedSTOFactory module was not added" ); @@ -384,112 +368,113 @@ contract('ModuleRegistry', accounts => { assert.equal(_reputation.length, 1); }); - it("Should successfully add verified module", async() => { - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, {from: account_polymath}); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, {from: account_polymath}); + it("Should successfully add verified module", async () => { + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], permissionManagerKey, "module doesn't get deployed"); }); - it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower", async() => { - I_TestSTOFactory = await TestSTOFactory.new(I_PolyToken.address, 0, 0, 0, {from: account_polymath}); - await I_MRProxied.registerModule(I_TestSTOFactory.address, {from: account_polymath}); - await I_MRProxied.verifyModule(I_TestSTOFactory.address, true, {from: account_polymath}); + it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower", async () => { + I_TestSTOFactory = await TestSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + await I_MRProxied.registerModule(I_TestSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_TestSTOFactory.address, true, { from: account_polymath }); // Taking the snapshot the revert the changes from here let id = await takeSnapshot(); - await I_TestSTOFactory.changeSTVersionBounds("lowerBound", [0,1,0], {from: account_polymath}); - let _lstVersion = await I_TestSTOFactory.getLowerSTVersionBounds.call() - assert.equal(_lstVersion[2],0); - assert.equal(_lstVersion[1],1); - let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); - + await I_TestSTOFactory.changeSTVersionBounds("lowerBound", [0, 1, 0], { from: account_polymath }); + let _lstVersion = await I_TestSTOFactory.getLowerSTVersionBounds.call(); + assert.equal(_lstVersion[2], 0); + assert.equal(_lstVersion[1], 1); + let bytesData = encodeModuleCall( + ["uint256", "uint256", "uint256", "string"], + [latestTime(), latestTime() + duration.days(1), cap, "Test STO"] + ); + await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); await revertToSnapshot(id); - }) + }); - it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --upper", async() => { - await I_TestSTOFactory.changeSTVersionBounds("upperBound", [0,0,1], {from: account_polymath}); - let _ustVersion = await I_TestSTOFactory.getUpperSTVersionBounds.call() - assert.equal(_ustVersion[0],0); - assert.equal(_ustVersion[2],1); + it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --upper", async () => { + await I_TestSTOFactory.changeSTVersionBounds("upperBound", [0, 0, 1], { from: account_polymath }); + let _ustVersion = await I_TestSTOFactory.getUpperSTVersionBounds.call(); + assert.equal(_ustVersion[0], 0); + assert.equal(_ustVersion[2], 1); await I_STRProxied.setProtocolVersion(I_STFactory.address, 1, 0, 1); // Generate the new securityToken let newSymbol = "toro"; await I_PolyToken.getTokens(web3.utils.toWei("500"), account_issuer); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), {from: account_issuer}); - await I_STRProxied.registerTicker(account_issuer, newSymbol, name, {from: account_issuer}); - let tx = await I_STRProxied.generateSecurityToken(name, newSymbol, tokenDetails, true, {from: account_issuer}); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: account_issuer }); + await I_STRProxied.registerTicker(account_issuer, newSymbol, name, { from: account_issuer }); + let tx = await I_STRProxied.generateSecurityToken(name, newSymbol, tokenDetails, true, { from: account_issuer }); assert.equal(tx.logs[1].args._ticker, newSymbol.toUpperCase()); I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + let bytesData = encodeModuleCall( + ["uint256", "uint256", "uint256", "string"], + [latestTime(), latestTime() + duration.days(1), cap, "Test STO"] + ); - let bytesData = encodeModuleCall(['uint256', 'uint256', 'uint256', 'string'],[latestTime(), (latestTime() + duration.days(1)), cap, "Test STO"]); - await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, 0, 0, { from: token_owner })); }); - }); - describe("Test case for the getModulesByTypeAndToken()", async() => { - - it("Should get the list of available modules when the customModulesAllowed", async() => { + describe("Test case for the getModulesByTypeAndToken()", async () => { + it("Should get the list of available modules when the customModulesAllowed", async () => { let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); assert.equal(_list[0], I_CappedSTOFactory2.address); - }) + }); - it("Should get the list of available modules when the customModulesAllowed is not allowed", async() => { + it("Should get the list of available modules when the customModulesAllowed is not allowed", async () => { await I_FeatureRegistry.setFeatureStatus("customModulesAllowed", false, { from: account_polymath }); let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); assert.equal(_list.length, 0); - }) - }) - - describe("Test cases for getters", async() => { + }); + }); - it("Check getter - ", async() => { - console.log("getModulesByType:") + describe("Test cases for getters", async () => { + it("Check getter - ", async () => { + console.log("getModulesByType:"); for (let i = 0; i < 5; i++) { let _list = await I_MRProxied.getModulesByType.call(i); console.log("Type: " + i + ":" + _list); } - console.log("getModulesByTypeAndToken:") + console.log("getModulesByTypeAndToken:"); for (let i = 0; i < 5; i++) { let _list = await I_MRProxied.getModulesByTypeAndToken.call(i, I_SecurityToken.address); console.log("Type: " + i + ":" + _list); } - console.log("getTagsByType:") + console.log("getTagsByType:"); for (let i = 0; i < 5; i++) { let _list = await I_MRProxied.getTagsByType.call(i); console.log("Type: " + i + ":" + _list[1]); console.log("Type: " + i + ":" + _list[0].map(x => web3.utils.toAscii(x))); } - console.log("getTagsByTypeAndToken:") + console.log("getTagsByTypeAndToken:"); for (let i = 0; i < 5; i++) { let _list = await I_MRProxied.getTagsByTypeAndToken.call(i, I_SecurityToken.address); console.log("Type: " + i + ":" + _list[1]); console.log("Type: " + i + ":" + _list[0].map(x => web3.utils.toAscii(x))); } - }) - + }); }); - describe("Test cases for removeModule()", async() => { - - it("Should fail if msg.sender not curator or owner", async() => { - + describe("Test cases for removeModule()", async () => { + it("Should fail if msg.sender not curator or owner", async () => { await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_temp })); }); - it("Should successfully remove module and delete data if msg.sender is curator", async() => { + it("Should successfully remove module and delete data if msg.sender is curator", async () => { let snap = await takeSnapshot(); let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; - assert.equal(sto1,I_CappedSTOFactory1.address); - assert.equal(sto2,I_CappedSTOFactory2.address); + assert.equal(sto1, I_CappedSTOFactory1.address); + assert.equal(sto2, I_CappedSTOFactory2.address); assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); let tx = await I_MRProxied.removeModule(sto1, { from: account_polymath }); @@ -500,7 +485,7 @@ contract('ModuleRegistry', accounts => { let sto2_end = (await I_MRProxied.getModulesByType.call(3))[1]; // re-ordering - assert.equal(sto2_end,sto2); + assert.equal(sto2_end, sto2); // delete related data assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto1)), 0); assert.equal(await I_MRProxied.getReputationByFactory.call(sto1), 0); @@ -510,12 +495,12 @@ contract('ModuleRegistry', accounts => { await revertToSnapshot(snap); }); - it("Should successfully remove module and delete data if msg.sender is owner", async() => { + it("Should successfully remove module and delete data if msg.sender is owner", async () => { let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; - assert.equal(sto1,I_CappedSTOFactory1.address); - assert.equal(sto2,I_CappedSTOFactory2.address); + assert.equal(sto1, I_CappedSTOFactory1.address); + assert.equal(sto2, I_CappedSTOFactory2.address); assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); let tx = await I_MRProxied.removeModule(sto2, { from: token_owner }); @@ -526,7 +511,7 @@ contract('ModuleRegistry', accounts => { let sto1_end = (await I_MRProxied.getModulesByType.call(3))[0]; // re-ordering - assert.equal(sto1_end,sto1); + assert.equal(sto1_end, sto1); // delete related data assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto2)), 0); assert.equal(await I_MRProxied.getReputationByFactory.call(sto2), 0); @@ -534,54 +519,46 @@ contract('ModuleRegistry', accounts => { assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto2)), false); }); - it("Should fail if module already removed", async() => { - + it("Should fail if module already removed", async () => { await catchRevert(I_MRProxied.removeModule(I_CappedSTOFactory2.address, { from: account_polymath })); }); - - }); - - describe("Test cases for IRegistry functionality", async() => { - - describe("Test cases for reclaiming funds", async() => { - - it("Should successfully reclaim POLY tokens", async() => { - await I_PolyToken.getTokens(web3.utils.toWei("1"), I_MRProxied.address); - let bal1 = await I_PolyToken.balanceOf.call(account_polymath); - await I_MRProxied.reclaimERC20(I_PolyToken.address); - let bal2 = await I_PolyToken.balanceOf.call(account_polymath); - assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); - }); - }); - describe("Test cases for pausing the contract", async() => { - - it("Should fail to pause if msg.sender is not owner", async() => { - - await catchRevert(I_MRProxied.pause({ from: account_temp })); + describe("Test cases for IRegistry functionality", async () => { + describe("Test cases for reclaiming funds", async () => { + it("Should successfully reclaim POLY tokens", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1"), I_MRProxied.address); + let bal1 = await I_PolyToken.balanceOf.call(account_polymath); + await I_MRProxied.reclaimERC20(I_PolyToken.address); + let bal2 = await I_PolyToken.balanceOf.call(account_polymath); + assert.isAtLeast( + bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), + bal2.dividedBy(new BigNumber(10).pow(18)).toNumber() + ); + }); }); - it("Should successfully pause the contract", async() => { - await I_MRProxied.pause({ from: account_polymath }); - let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); - assert.isOk(status); - }); - - it("Should fail to unpause if msg.sender is not owner", async() => { - - await catchRevert(I_MRProxied.unpause({ from: account_temp })); - }); - - it("Should successfully unpause the contract", async() => { - await I_MRProxied.unpause({ from: account_polymath }); - let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); - assert.isNotOk(status); + describe("Test cases for pausing the contract", async () => { + it("Should fail to pause if msg.sender is not owner", async () => { + await catchRevert(I_MRProxied.pause({ from: account_temp })); + }); + + it("Should successfully pause the contract", async () => { + await I_MRProxied.pause({ from: account_polymath }); + let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); + assert.isOk(status); + }); + + it("Should fail to unpause if msg.sender is not owner", async () => { + await catchRevert(I_MRProxied.unpause({ from: account_temp })); + }); + + it("Should successfully unpause the contract", async () => { + await I_MRProxied.unpause({ from: account_polymath }); + let status = await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); + assert.isNotOk(status); + }); }); - }); - }); - }); - }); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index b43ce6b30..349710525 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -1,22 +1,21 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { setUpPolymathNetwork } from './helpers/createInstances'; -import { catchRevert } from './helpers/exceptions'; - -const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const PercentageTransferManagerFactory = artifacts.require('./PercentageTransferManagerFactory.sol'); -const PercentageTransferManager = artifacts.require('./PercentageTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('PercentageTransferManager', accounts => { - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { catchRevert } from "./helpers/exceptions"; + +const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const PercentageTransferManagerFactory = artifacts.require("./PercentageTransferManagerFactory.sol"); +const PercentageTransferManager = artifacts.require("./PercentageTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("PercentageTransferManager", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -70,19 +69,23 @@ contract('PercentageTransferManager', accounts => { const initRegFee = web3.utils.toWei("250"); // PercentageTransferManager details - const holderPercentage = 70 * 10**16; // Maximum number of token holders - - let bytesSTO = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_maxHolderPercentage' - } - ] - }, [holderPercentage]); - - before(async() => { + const holderPercentage = 70 * 10 ** 16; // Maximum number of token holders + + let bytesSTO = web3.eth.abi.encodeFunctionCall( + { + name: "configure", + type: "function", + inputs: [ + { + type: "uint256", + name: "_maxHolderPercentage" + } + ] + }, + [holderPercentage] + ); + + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -95,12 +98,25 @@ contract('PercentageTransferManager', accounts => { let instances = await setUpPolymathNetwork(account_polymath, token_owner); - [I_PolymathRegistry, I_PolyToken, I_FeatureRegistry, I_ModuleRegistry, I_ModuleRegistryProxy, I_MRProxied, I_GeneralTransferManagerFactory, - I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied] = instances; + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 4(b): Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -109,7 +125,9 @@ contract('PercentageTransferManager', accounts => { ); // STEP 4(c): Deploy the PercentageTransferManager - I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_PercentageTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -117,25 +135,30 @@ contract('PercentageTransferManager', accounts => { ); // STEP 4(d): Deploy the PercentageTransferManager - P_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); + P_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new( + I_PolyToken.address, + web3.utils.toWei("500", "ether"), + 0, + 0, + { from: account_polymath } + ); assert.notEqual( P_PercentageTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "PercentageTransferManagerFactory contract was not deployed" ); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the PercentageTransferManagerFactory - await I_MRProxied.registerModule(I_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PercentageTransferManagerFactory.address, true, { from: account_polymath }); + // (C) : Register the PercentageTransferManagerFactory + await I_MRProxied.registerModule(I_PercentageTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_PercentageTransferManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the Paid PercentageTransferManagerFactory - await I_MRProxied.registerModule(P_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_PercentageTransferManagerFactory.address, true, { from: account_polymath }); + // (C) : Register the Paid PercentageTransferManagerFactory + await I_MRProxied.registerModule(P_PercentageTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_PercentageTransferManagerFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` @@ -156,11 +179,10 @@ contract('PercentageTransferManager', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -175,28 +197,21 @@ contract('PercentageTransferManager', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - }); - describe("Buy tokens using on-chain whitelist", async() => { - - it("Should Buy the tokens", async() => { + describe("Buy tokens using on-chain whitelist", async () => { + it("Should Buy the tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -208,23 +223,25 @@ contract('PercentageTransferManager', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(5000); // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Should Buy some more tokens", async() => { + it("Should Buy some more tokens", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -236,33 +253,43 @@ contract('PercentageTransferManager', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("1", "ether")); }); it("Should successfully attach the PercentageTransferManagerr factory with the security token", async () => { - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert(I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner })); + await catchRevert( + I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }) + ); }); it("Should successfully attach the PercentageTransferManager factory with the security token", async () => { let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + const tx = await I_SecurityToken.addModule( + P_PercentageTransferManagerFactory.address, + bytesSTO, + web3.utils.toWei("500", "ether"), + 0, + { from: token_owner } + ); assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "PercentageTransferManager", "PercentageTransferManagerFactory module was not added" ); @@ -274,16 +301,14 @@ contract('PercentageTransferManager', accounts => { const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "PercentageTransferManager", "PercentageTransferManager module was not added" ); I_PercentageTransferManager = PercentageTransferManager.at(tx.logs[2].args._module); }); - it("Add a new token holder", async() => { - + it("Add a new token holder", async () => { let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor3, latestTime(), @@ -293,98 +318,92 @@ contract('PercentageTransferManager', accounts => { { from: account_issuer, gas: 6000000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor3.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor3, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Should pause the tranfers at transferManager level", async() => { - let tx = await I_PercentageTransferManager.pause({from: token_owner}); + it("Should pause the tranfers at transferManager level", async () => { + let tx = await I_PercentageTransferManager.pause({ from: token_owner }); }); - it("Should still be able to transfer between existing token holders up to limit", async() => { + it("Should still be able to transfer between existing token holders up to limit", async () => { // Add the Investor in to the whitelist // Mint some tokens - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("1", "ether"), { from: account_investor2 }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Should unpause the tranfers at transferManager level", async() => { - await I_PercentageTransferManager.unpause({from: token_owner}); - }) + it("Should unpause the tranfers at transferManager level", async () => { + await I_PercentageTransferManager.unpause({ from: token_owner }); + }); - it("Should not be able to transfer between existing token holders over limit", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 })); + it("Should not be able to transfer between existing token holders over limit", async () => { + await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei("2", "ether"), { from: account_investor1 })); }); - it("Modify holder percentage to 100", async() => { + it("Modify holder percentage to 100", async () => { // Add the Investor in to the whitelist // Mint some tokens - await I_PercentageTransferManager.changeHolderPercentage(100 * 10**16, { from: token_owner }); + await I_PercentageTransferManager.changeHolderPercentage(100 * 10 ** 16, { from: token_owner }); - assert.equal( - (await I_PercentageTransferManager.maxHolderPercentage()).toNumber(), - 100 * 10**16 - ); + assert.equal((await I_PercentageTransferManager.maxHolderPercentage()).toNumber(), 100 * 10 ** 16); }); - it("Should be able to transfer between existing token holders up to limit", async() => { + it("Should be able to transfer between existing token holders up to limit", async () => { await I_PercentageTransferManager.modifyWhitelist(account_investor3, false, { from: token_owner }); - await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); + await I_SecurityToken.transfer(account_investor3, web3.utils.toWei("2", "ether"), { from: account_investor1 }); }); - it("Should be able to whitelist address and then transfer regardless of holders", async() => { - await I_PercentageTransferManager.changeHolderPercentage(30 * 10**16, { from: token_owner }); - await I_PercentageTransferManager.modifyWhitelist(account_investor1, true, { from: token_owner }); - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor3 }); + it("Should be able to whitelist address and then transfer regardless of holders", async () => { + await I_PercentageTransferManager.changeHolderPercentage(30 * 10 ** 16, { from: token_owner }); + await I_PercentageTransferManager.modifyWhitelist(account_investor1, true, { from: token_owner }); + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("2", "ether"), { from: account_investor3 }); }); - it("Should get the permission", async() => { + it("Should get the permission", async () => { let perm = await I_PercentageTransferManager.getPermissions.call(); assert.equal(perm.length, 1); }); - }); - describe("Percentage Transfer Manager Factory test cases", async() => { - - it("Should get the exact details of the factory", async() => { - assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(),0); - assert.equal((await I_PercentageTransferManagerFactory.getTypes.call())[0],2); - assert.equal(web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "PercentageTransferManager", - "Wrong Module added"); - assert.equal(await I_PercentageTransferManagerFactory.getDescription.call(), - "Restrict the number of investors", - "Wrong Module added"); - assert.equal(await I_PercentageTransferManagerFactory.getTitle.call(), - "Percentage Transfer Manager", - "Wrong Module added"); - assert.equal(await I_PercentageTransferManagerFactory.getInstructions.call(), - "Allows an issuer to restrict the total number of non-zero token holders", - "Wrong Module added"); - + describe("Percentage Transfer Manager Factory test cases", async () => { + it("Should get the exact details of the factory", async () => { + assert.equal(await I_PercentageTransferManagerFactory.setupCost.call(), 0); + assert.equal((await I_PercentageTransferManagerFactory.getTypes.call())[0], 2); + assert.equal( + web3.utils.toAscii(await I_PercentageTransferManagerFactory.getName.call()).replace(/\u0000/g, ""), + "PercentageTransferManager", + "Wrong Module added" + ); + assert.equal( + await I_PercentageTransferManagerFactory.getDescription.call(), + "Restrict the number of investors", + "Wrong Module added" + ); + assert.equal(await I_PercentageTransferManagerFactory.getTitle.call(), "Percentage Transfer Manager", "Wrong Module added"); + assert.equal( + await I_PercentageTransferManagerFactory.getInstructions.call(), + "Allows an issuer to restrict the total number of non-zero token holders", + "Wrong Module added" + ); }); - it("Should get the tags of the factory", async() => { + it("Should get the tags of the factory", async () => { let tags = await I_PercentageTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "Percentage"); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ""), "Percentage"); }); }); - }); diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index 7b919ac2b..a59d6c553 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -1,30 +1,30 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const PreSaleSTOFactory = artifacts.require('./PreSaleSTOFactory.sol'); -const PreSaleSTO = artifacts.require('./PreSaleSTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('PreSaleSTO', accounts => { +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); +const PreSaleSTO = artifacts.require("./PreSaleSTO.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("PreSaleSTO", accounts => { // Accounts Variable declaration let account_polymath; let account_investor1; @@ -80,12 +80,11 @@ contract('PreSaleSTO', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); let endTime; - const STOParameters = ['uint256']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { + const STOParameters = ["uint256"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -98,32 +97,30 @@ contract('PreSaleSTO', accounts => { // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 2: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -133,7 +130,9 @@ contract('PreSaleSTO', accounts => { // STEP 3: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -153,36 +152,41 @@ contract('PreSaleSTO', accounts => { // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // STEP 5: Register the Modules with the ModuleRegistry contract @@ -218,11 +222,10 @@ contract('PreSaleSTO', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol); }); @@ -237,38 +240,33 @@ contract('PreSaleSTO', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should fail to launch the STO due to endTime is 0", async () => { let bytesSTO = encodeModuleCall(STOParameters, [0]); - + await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); }); it("Should successfully attach the STO factory with the security token", async () => { - endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time + endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time let bytesSTO = encodeModuleCall(STOParameters, [endTime]); const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], stoKey, "PreSaleSTO doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "PreSaleSTO", "PreSaleSTOFactory module was not added" ); @@ -277,133 +275,107 @@ contract('PreSaleSTO', accounts => { }); describe("verify the data of STO", async () => { - - it("Should verify the configuration of the STO", async() => { - assert.equal( - (await I_PreSaleSTO.endTime.call()).toNumber(), - endTime, - "STO Configuration doesn't set as expected" - ); + it("Should verify the configuration of the STO", async () => { + assert.equal((await I_PreSaleSTO.endTime.call()).toNumber(), endTime, "STO Configuration doesn't set as expected"); }); - it("Should get the permissions", async() => { - let perm = await I_PreSaleSTO.getPermissions.call(); - assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), "PRE_SALE_ADMIN"); + it("Should get the permissions", async () => { + let perm = await I_PreSaleSTO.getPermissions.call(); + assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ""), "PRE_SALE_ADMIN"); }); }); - describe("Buy tokens", async() => { - + describe("Buy tokens", async () => { it("Should allocate the tokens -- failed due to investor not on whitelist", async () => { - - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0)); + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei("1", "ether"), 0)); }); - it("Should Buy the tokens", async() => { + it("Should Buy the tokens", async () => { fromTime = latestTime(); toTime = fromTime + duration.days(100); expiryTime = toTime + duration.days(100); // Add the Investor in to the whitelist - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 6000000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 6000000 + }); assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); // Jump time await increaseTime(duration.days(1)); - await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_issuer }); + await I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether"), 0, { + from: account_issuer + }); - assert.equal( - (await I_PreSaleSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); + assert.equal((await I_PreSaleSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); console.log(await I_PreSaleSTO.getNumberInvestors.call()); assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 1); // assert.isTrue(false); - }); it("Should allocate the tokens -- failed due to msg.sender is not pre sale admin", async () => { - - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether'), 0, {from: account_fundsReceiver })); + await catchRevert( + I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether"), 0, { + from: account_fundsReceiver + }) + ); }); - it("Should allocate tokens to multiple investors", async() => { + it("Should allocate tokens to multiple investors", async () => { fromTime = latestTime(); toTime = fromTime + duration.days(100); expiryTime = toTime + duration.days(100); // Add the Investor in to the whitelist - let tx1 = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 6000000 - }); + let tx1 = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 6000000 + }); assert.equal(tx1.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); // Add the Investor in to the whitelist - let tx2 = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - fromTime, - toTime, - expiryTime, - true, - { - from: account_issuer, - gas: 6000000 - }); + let tx2 = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { + from: account_issuer, + gas: 6000000 + }); assert.equal(tx2.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); - await I_PreSaleSTO.allocateTokensMulti([account_investor2, account_investor3], [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], [0,0], [web3.utils.toWei('1000', 'ether'), web3.utils.toWei('1000', 'ether')], {from: account_issuer }); - - assert.equal( - (await I_PreSaleSTO.getRaised.call(1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 2000 + await I_PreSaleSTO.allocateTokensMulti( + [account_investor2, account_investor3], + [web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether")], + [0, 0], + [web3.utils.toWei("1000", "ether"), web3.utils.toWei("1000", "ether")], + { from: account_issuer } ); + + assert.equal((await I_PreSaleSTO.getRaised.call(1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2000); assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 3); }); - it("Should failed at the time of buying the tokens -- Because STO has started", async() => { + it("Should failed at the time of buying the tokens -- Because STO has started", async () => { await increaseTime(duration.days(100)); // increased beyond the end time of the STO - - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei('1', 'ether'), 0, {from: account_issuer})); - }); + await catchRevert( + I_PreSaleSTO.allocateTokens(account_investor1, 1000, web3.utils.toWei("1", "ether"), 0, { from: account_issuer }) + ); + }); }); - describe("Reclaim poly sent to STO by mistake", async() => { - - it("Should fail to reclaim POLY because token contract address is 0 address", async() => { - let value = web3.utils.toWei('100','ether'); + describe("Reclaim poly sent to STO by mistake", async () => { + it("Should fail to reclaim POLY because token contract address is 0 address", async () => { + let value = web3.utils.toWei("100", "ether"); await I_PolyToken.getTokens(value, account_investor1); await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); - - await catchRevert(I_PreSaleSTO.reclaimERC20('0x0000000000000000000000000000000000000000', { from: token_owner })); + await catchRevert(I_PreSaleSTO.reclaimERC20("0x0000000000000000000000000000000000000000", { from: token_owner })); }); - it("Should successfully reclaim POLY", async() => { - let value = web3.utils.toWei('100','ether'); + it("Should successfully reclaim POLY", async () => { + let value = web3.utils.toWei("100", "ether"); await I_PolyToken.getTokens(value, account_investor1); let initInvestorBalance = await I_PolyToken.balanceOf(account_investor1); let initOwnerBalance = await I_PolyToken.balanceOf(token_owner); @@ -411,32 +383,49 @@ contract('PreSaleSTO', accounts => { await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); await I_PreSaleSTO.reclaimERC20(I_PolyToken.address, { from: token_owner }); - assert.equal((await I_PolyToken.balanceOf(account_investor1)).toNumber(), initInvestorBalance.sub(value).toNumber(), "tokens are not transfered out from investor account"); - assert.equal((await I_PolyToken.balanceOf(token_owner)).toNumber(), initOwnerBalance.add(value).add(initContractBalance).toNumber(), "tokens are not added to the owner account"); - assert.equal((await I_PolyToken.balanceOf(I_PreSaleSTO.address)).toNumber(), 0, "tokens are not trandfered out from STO contract"); + assert.equal( + (await I_PolyToken.balanceOf(account_investor1)).toNumber(), + initInvestorBalance.sub(value).toNumber(), + "tokens are not transfered out from investor account" + ); + assert.equal( + (await I_PolyToken.balanceOf(token_owner)).toNumber(), + initOwnerBalance + .add(value) + .add(initContractBalance) + .toNumber(), + "tokens are not added to the owner account" + ); + assert.equal( + (await I_PolyToken.balanceOf(I_PreSaleSTO.address)).toNumber(), + 0, + "tokens are not trandfered out from STO contract" + ); }); }); - describe("Test cases for the PresaleSTOFactory", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_PreSaleSTOFactory.setupCost.call(),0); - assert.equal((await I_PreSaleSTOFactory.getTypes.call())[0],3); - assert.equal(web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()) - .replace(/\u0000/g, ''), - "PreSaleSTO", - "Wrong Module added"); - assert.equal(await I_PreSaleSTOFactory.getDescription.call(), - "Allows Issuer to configure pre-sale token allocations", - "Wrong Module added"); - assert.equal(await I_PreSaleSTOFactory.getTitle.call(), - "PreSale STO", - "Wrong Module added"); - assert.equal(await I_PreSaleSTOFactory.getInstructions.call(), - "Configure and track pre-sale token allocations", - "Wrong Module added"); + describe("Test cases for the PresaleSTOFactory", async () => { + it("should get the exact details of the factory", async () => { + assert.equal(await I_PreSaleSTOFactory.setupCost.call(), 0); + assert.equal((await I_PreSaleSTOFactory.getTypes.call())[0], 3); + assert.equal( + web3.utils.toAscii(await I_PreSaleSTOFactory.getName.call()).replace(/\u0000/g, ""), + "PreSaleSTO", + "Wrong Module added" + ); + assert.equal( + await I_PreSaleSTOFactory.getDescription.call(), + "Allows Issuer to configure pre-sale token allocations", + "Wrong Module added" + ); + assert.equal(await I_PreSaleSTOFactory.getTitle.call(), "PreSale STO", "Wrong Module added"); + assert.equal( + await I_PreSaleSTOFactory.getInstructions.call(), + "Configure and track pre-sale token allocations", + "Wrong Module added" + ); let tags = await I_PreSaleSTOFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''),"Presale"); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ""), "Presale"); }); - }); - + }); }); diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index ec42ac618..27970c102 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -1,35 +1,32 @@ -import latestTime from './helpers/latestTime'; -import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); -const DummySTO = artifacts.require('./DummySTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryMock = artifacts.require('./SecurityTokenRegistryMock.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyToken = artifacts.require('./PolyToken.sol'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - - -contract('SecurityTokenRegistry', accounts => { - - +import latestTime from "./helpers/latestTime"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); +const DummySTO = artifacts.require("./DummySTO.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyToken = artifacts.require("./PolyToken.sol"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("SecurityTokenRegistry", accounts => { // Accounts Variable declaration let account_polymath; let account_investor1; @@ -92,17 +89,17 @@ contract('SecurityTokenRegistry', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const newRegFee = web3.utils.toWei("300"); + const newRegFee = web3.utils.toWei("300"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; + const STOParameters = ["uint256", "uint256", "uint256", "string"]; - // Capped STO details - const cap = web3.utils.toWei("10000"); - const someString = "Hello string"; + // Capped STO details + const cap = web3.utils.toWei("10000"); + const someString = "Hello string"; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -114,30 +111,28 @@ contract('SecurityTokenRegistry', accounts => { token_owner = account_issuer; dummy_token = accounts[3]; - // ----------- POLYMATH NETWORK Configuration ------------ + // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 2: Deploy the GeneralTransferManagerFactory @@ -152,7 +147,9 @@ contract('SecurityTokenRegistry', accounts => { // STEP 3: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -160,20 +157,15 @@ contract('SecurityTokenRegistry', accounts => { "GeneralDelegateManagerFactory contract was not deployed" ); - // Step 6: Deploy the STversionProxy contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // STEP 8: Deploy the CappedSTOFactory - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 1000 * Math.pow(10, 18), 0, 0,{ from: token_owner }); + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 1000 * Math.pow(10, 18), 0, 0, { from: token_owner }); assert.notEqual( I_DummySTOFactory.address.valueOf(), @@ -183,37 +175,35 @@ contract('SecurityTokenRegistry', accounts => { // Step 9: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); // Step 9 (a): Deploy the proxy - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - // Step 10: Deploy the FeatureRegistry + // Step 10: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); assert.notEqual( I_FeatureRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "FeatureRegistry contract was not deployed", + "FeatureRegistry contract was not deployed" ); //Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // STEP 4: Register the Modules with the ModuleRegistry contract @@ -246,67 +236,127 @@ contract('SecurityTokenRegistry', accounts => { `); }); - describe("Test the initialize the function", async() => { - - it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, ["0x0000000000000000000000000000000000000000", I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + describe("Test the initialize the function", async () => { + it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + "0x0000000000000000000000000000000000000000", + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }), "tx-> revert because polymathRegistry address is 0x" ); - }) + }); - it("Should successfully update the implementation address -- fail because STFactory address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, "0x0000000000000000000000000000000000000000", initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + it("Should successfully update the implementation address -- fail because STFactory address is 0x", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + "0x0000000000000000000000000000000000000000", + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }), "tx-> revert because STFactory address is 0x" ); }); - it("Should successfully update the implementation address -- fail because STLaunch fee is 0", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, 0, initRegFee, I_PolyToken.address, account_polymath]); + it("Should successfully update the implementation address -- fail because STLaunch fee is 0", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + 0, + initRegFee, + I_PolyToken.address, + account_polymath + ]); catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }), "tx-> revert because STLaunch fee is 0" ); }); - it("Should successfully update the implementation address -- fail because tickerRegFee fee is 0", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, 0, I_PolyToken.address, account_polymath]); + it("Should successfully update the implementation address -- fail because tickerRegFee fee is 0", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + 0, + I_PolyToken.address, + account_polymath + ]); catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }), "tx-> revert because tickerRegFee is 0" ); }); - it("Should successfully update the implementation address -- fail because PolyToken address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, "0x0000000000000000000000000000000000000000", account_polymath]); + it("Should successfully update the implementation address -- fail because PolyToken address is 0x", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + "0x0000000000000000000000000000000000000000", + account_polymath + ]); catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }), "tx-> revert because PolyToken address is 0x" ); }); - it("Should successfully update the implementation address -- fail because owner address is 0x", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, "0x0000000000000000000000000000000000000000"]); + it("Should successfully update the implementation address -- fail because owner address is 0x", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + "0x0000000000000000000000000000000000000000" + ]); catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}), + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }), "tx-> revert because owner address is 0x" ); }); - it("Should successfully update the implementation address", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + it("Should successfully update the implementation address", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); I_STRProxied = SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); }); - }) - - - describe(" Test cases of the registerTicker", async() => { + }); - it("verify the intial parameters", async() => { + describe(" Test cases of the registerTicker", async () => { + it("verify the intial parameters", async () => { let intialised = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("initialised")); assert.isTrue(intialised, "Should be true"); @@ -329,38 +379,42 @@ contract('SecurityTokenRegistry', accounts => { assert.equal(owner, account_polymath, "Should be the address of the registry owner"); }); - it("Can't call the intialize function again", async() => { + it("Can't call the intialize function again", async () => { catchRevert( - I_STRProxied.initialize(I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath), + I_STRProxied.initialize( + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ), "tx revert -> Can't call the intialize function again" ); - }) + }); - it("Should fail to register ticker if tickerRegFee not approved", async() => { + it("Should fail to register ticker if tickerRegFee not approved", async () => { catchRevert( I_STRProxied.registerTicker(account_temp, symbol, name, { from: account_temp }), "tx revert -> POLY allowance not provided for registration fee" ); }); - it("Should fail to register ticker if owner is 0x", async() => { + it("Should fail to register ticker if owner is 0x", async () => { await I_PolyToken.getTokens(initRegFee, account_temp); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); - + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp }); + catchRevert( I_STRProxied.registerTicker("0x0000000000000000000000000000000000000000", symbol, name, { from: account_temp }), "tx revert -> owner should not be 0x" - ); + ); }); - it("Should fail to register ticker due to the symbol length is 0", async() => { - catchRevert( - I_STRProxied.registerTicker(account_temp, "", name, { from: account_temp }), - "tx revert -> Symbol Length is 0" - ); + it("Should fail to register ticker due to the symbol length is 0", async () => { + catchRevert(I_STRProxied.registerTicker(account_temp, "", name, { from: account_temp }), "tx revert -> Symbol Length is 0"); }); - it("Should fail to register ticker due to the symbol length is greater than 10", async() => { + it("Should fail to register ticker due to the symbol length is greater than 10", async () => { catchRevert( I_STRProxied.registerTicker(account_temp, "POLYMATHNET", name, { from: account_temp }), "tx revert -> Symbol Length is greater than 10" @@ -373,10 +427,10 @@ contract('SecurityTokenRegistry', accounts => { assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); }); - it("Should fail to register same symbol again", async() => { + it("Should fail to register same symbol again", async () => { // Give POLY to token issuer await I_PolyToken.getTokens(initRegFee, token_owner); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); // Call registration function catchRevert( I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }), @@ -384,83 +438,72 @@ contract('SecurityTokenRegistry', accounts => { ); }); - it("Should successfully register pre registerd ticker if expiry is reached", async() => { + it("Should successfully register pre registerd ticker if expiry is reached", async () => { await increaseTime(5184000 + 100); // 60(5184000) days of expiry + 100 sec for buffer - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); }); - it("Should fail to register ticker if registration is paused", async() => { - await I_STRProxied.pause({ from: account_polymath}); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - + it("Should fail to register ticker if registration is paused", async () => { + await I_STRProxied.pause({ from: account_polymath }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + catchRevert( I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }), "tx revert -> Registration is paused" ); }); - it("Should fail to pause if already paused", async() => { - catchRevert( - I_STRProxied.pause({ from: account_polymath}), - "tx revert -> Registration is already paused" - ); + it("Should fail to pause if already paused", async () => { + catchRevert(I_STRProxied.pause({ from: account_polymath }), "tx revert -> Registration is already paused"); }); - it("Should successfully register ticker if registration is unpaused", async() => { - await I_STRProxied.unpause({ from: account_polymath}); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + it("Should successfully register ticker if registration is unpaused", async () => { + await I_STRProxied.unpause({ from: account_polymath }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let tx = await I_STRProxied.registerTicker(token_owner, "AAA", name, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner, `Owner should be the ${token_owner}`); assert.equal(tx.logs[0].args._ticker, "AAA", `Symbol should be AAA`); }); - it("Should fail to unpause if already unpaused", async() => { - catchRevert( - I_STRProxied.unpause({ from: account_polymath}), - "tx revert -> Registration is already unpaused" - ); + it("Should fail to unpause if already unpaused", async () => { + catchRevert(I_STRProxied.unpause({ from: account_polymath }), "tx revert -> Registration is already unpaused"); }); }); - describe("Test cases for the expiry limit", async() => { - - it("Should fail to set the expiry limit because msg.sender is not owner", async() => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_temp}), - "tx revert -> msg.sender is not owner" - ); + describe("Test cases for the expiry limit", async () => { + it("Should fail to set the expiry limit because msg.sender is not owner", async () => { + catchRevert(I_STRProxied.changeExpiryLimit(duration.days(10), { from: account_temp }), "tx revert -> msg.sender is not owner"); }); - it("Should successfully set the expiry limit", async() => { - await I_STRProxied.changeExpiryLimit(duration.days(10), {from: account_polymath}); + it("Should successfully set the expiry limit", async () => { + await I_STRProxied.changeExpiryLimit(duration.days(10), { from: account_polymath }); assert.equal( - (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))) - .toNumber(), + (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))).toNumber(), duration.days(10), - "Failed to change the expiry limit"); + "Failed to change the expiry limit" + ); }); - it("Should fail to set the expiry limit because new expiry limit is lesser than one day", async() => { + it("Should fail to set the expiry limit because new expiry limit is lesser than one day", async () => { catchRevert( - I_STRProxied.changeExpiryLimit(duration.seconds(5000), {from: account_polymath}), + I_STRProxied.changeExpiryLimit(duration.seconds(5000), { from: account_polymath }), "tx revert -> New expiry limit is lesser than one day" - ) + ); }); }); - describe("Test cases for the getTickerDetails", async() => { - - it("Should get the details of the symbol", async() => { + describe("Test cases for the getTickerDetails", async () => { + it("Should get the details of the symbol", async () => { let tx = await I_STRProxied.getTickerDetails.call(symbol); assert.equal(tx[0], token_owner, "Should equal to the rightful owner of the ticker"); assert.equal(tx[3], name, `Name of the token should equal to ${name}`); assert.equal(tx[4], false, "Status if the symbol should be undeployed -- false"); }); - it("Should get the details of unregistered token", async() => { + it("Should get the details of unregistered token", async () => { let tx = await I_STRProxied.getTickerDetails.call("TORO"); assert.equal(tx[0], "0x0000000000000000000000000000000000000000", "Should be 0x as ticker is not exists in the registry"); assert.equal(tx[3], "", "Should be an empty string"); @@ -468,59 +511,58 @@ contract('SecurityTokenRegistry', accounts => { }); }); - describe("Generate SecurityToken", async() => { - - it("Should get the ticker details successfully and prove the data is not storing in to the logic contract", async() => { - let data = await I_STRProxied.getTickerDetails(symbol, {from: token_owner}); + describe("Generate SecurityToken", async () => { + it("Should get the ticker details successfully and prove the data is not storing in to the logic contract", async () => { + let data = await I_STRProxied.getTickerDetails(symbol, { from: token_owner }); assert.equal(data[0], token_owner, "Token owner should be equal"); assert.equal(data[3], name, "Name of the token should match with the registered symbol infor"); assert.equal(data[4], false, "Token is not launched yet so it should return False"); - data = await I_SecurityTokenRegistry.getTickerDetails(symbol, {from:token_owner}); + data = await I_SecurityTokenRegistry.getTickerDetails(symbol, { from: token_owner }); console.log("This is the data from the original securityTokenRegistry contract"); - assert.equal(data[0], '0x0000000000000000000000000000000000000000', "Token owner should be 0x"); - }) + assert.equal(data[0], "0x0000000000000000000000000000000000000000", "Token owner should be 0x"); + }); + + it("Should fail to generate new security token if fee not provided", async () => { + await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner }); - it("Should fail to generate new security token if fee not provided", async() => { - await I_PolyToken.approve(I_STRProxied.address, 0, { from: token_owner}); - catchRevert( I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), "tx revert -> POLY allowance not provided for registration fee" ); }); - it("Should fail to generate token if registration is paused", async() => { - await I_STRProxied.pause({ from: account_polymath}); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - + it("Should fail to generate token if registration is paused", async () => { + await I_STRProxied.pause({ from: account_polymath }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + catchRevert( I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), "tx revert -> Registration is paused" ); }); - it("Should fail to generate the securityToken -- Because ticker length is 0", async() => { - await I_STRProxied.unpause({ from: account_polymath}); + it("Should fail to generate the securityToken -- Because ticker length is 0", async () => { + await I_STRProxied.unpause({ from: account_polymath }); catchRevert( I_STRProxied.generateSecurityToken(name, "", tokenDetails, false, { from: token_owner }), "tx revert -> Zero ticker length is not allowed" - ) - }) + ); + }); - it("Should fail to generate the securityToken -- Because name length is 0", async() => { + it("Should fail to generate the securityToken -- Because name length is 0", async () => { catchRevert( I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: token_owner }), "tx revert -> 0 name length is not allowed" ); - }) + }); - it("Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker", async() => { + it("Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker", async () => { catchRevert( I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp }), "tx revert -> Because msg.sender is not the rightful owner of the ticker" - ) - }) + ); + }); it("Should generate the new security token with the same symbol as registered above", async () => { let _blockNo = latestBlock(); @@ -531,37 +573,31 @@ contract('SecurityTokenRegistry', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTrasnferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey, `Should be equal to the ${transferManagerKey}`); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); - it("Should fail to generate the SecurityToken when token is already deployed with the same symbol", async() => { + it("Should fail to generate the SecurityToken when token is already deployed with the same symbol", async () => { catchRevert( I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }), "tx revert -> Because ticker is already in use" ); - }) - + }); }); - describe("Generate SecurityToken v2", async() => { - - it("Should deploy the st version 2", async() => { + describe("Generate SecurityToken v2", async () => { + it("Should deploy the st version 2", async () => { // Step 7: Deploy the STFactory contract - I_STFactory002 = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory002 = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); assert.notEqual( I_STFactory002.address.valueOf(), "0x0000000000000000000000000000000000000000", - "STFactory002 contract was not deployed", + "STFactory002 contract was not deployed" ); await I_STRProxied.setProtocolVersion(I_STFactory002.address, 0, 2, 0, { from: account_polymath }); let _protocol = await I_STRProxied.getProtocolVersion.call(); @@ -571,14 +607,14 @@ contract('SecurityTokenRegistry', accounts => { }); it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol2, name2, { from : token_owner }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol2, name2, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); assert.equal(tx.logs[0].args._ticker, symbol2, `Symbol should be ${symbol2}`); }); - it("Should generate the new security token with version 2", async() => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + it("Should generate the new security token with version 2", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, { from: token_owner }); @@ -590,314 +626,350 @@ contract('SecurityTokenRegistry', accounts => { assert.equal(tokens[0], I_SecurityToken.address); assert.equal(tokens[1], I_SecurityToken002.address); - const log = await promisifyLogWatch(I_SecurityToken002.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken002.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); - }); - describe("Deploy the new SecurityTokenRegistry", async() => { - - it("Should deploy the new SecurityTokenRegistry contract logic", async() => { + describe("Deploy the new SecurityTokenRegistry", async () => { + it("Should deploy the new SecurityTokenRegistry contract logic", async () => { I_SecurityTokenRegistryV2 = await SecurityTokenRegistryMock.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistryV2.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); }); - it("Should fail to upgrade the logic contract of the STRProxy -- bad owner", async() => { - await I_STRProxied.pause({from: account_polymath}); - + it("Should fail to upgrade the logic contract of the STRProxy -- bad owner", async () => { + await I_STRProxied.pause({ from: account_polymath }); + catchRevert( - I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_temp}), + I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, { from: account_temp }), "tx revert -> bad owner" - ) - }) + ); + }); - it("Should upgrade the logic contract into the STRProxy", async() =>{ - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, {from: account_polymath}); + it("Should upgrade the logic contract into the STRProxy", async () => { + await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryV2.address, { from: account_polymath }); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); assert.isTrue(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")), "Paused value should be false"); }); - it("Should check the old data persist or not", async() => { + it("Should check the old data persist or not", async () => { let data = await I_STRProxied.getTickerDetails.call(symbol); assert.equal(data[0], token_owner, "Should be equal to the token owner address"); assert.equal(data[3], name, "Should be equal to the name of the token that is provided earlier"); assert.isTrue(data[4], "Token status should be deployed == true"); }); - it("Should unpause the logic contract", async() => { - await I_STRProxied.unpause({from: account_polymath}); + it("Should unpause the logic contract", async () => { + await I_STRProxied.unpause({ from: account_polymath }); assert.isFalse(await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")), "Paused value should be false"); }); - }) - - describe("Generate custom tokens", async() => { + }); - it("Should fail if msg.sender is not polymath", async() => { + describe("Generate custom tokens", async () => { + it("Should fail if msg.sender is not polymath", async () => { catchRevert( - I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_delegate}), + I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), { + from: account_delegate + }), "tx revert -> msg.sender is not polymath account" ); }); - it("Should fail to generate the custom security token -- name should not be 0 length ", async() => { + it("Should fail to generate the custom security token -- name should not be 0 length ", async () => { catchRevert( - I_STRProxied.modifySecurityToken("", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}), - "tx revert -> name should not be 0 length" + I_STRProxied.modifySecurityToken("", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), { + from: account_polymath + }), + "tx revert -> name should not be 0 length" ); }); - it("Should fail if ST address is 0 address", async() => { + it("Should fail if ST address is 0 address", async () => { catchRevert( - I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", latestTime(), {from: account_polymath}), + I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", latestTime(), { + from: account_polymath + }), "tx revert -> Security token address is 0" ); }); - it("Should fail if symbol length is 0", async() => { - catchRevert( - I_STRProxied.modifySecurityToken("", "", account_temp, dummy_token, "I am custom ST",latestTime(), {from: account_polymath}), + it("Should fail if symbol length is 0", async () => { + catchRevert( + I_STRProxied.modifySecurityToken("", "", account_temp, dummy_token, "I am custom ST", latestTime(), { + from: account_polymath + }), "tx revert -> zero length of the symbol is not allowed" - ); + ); }); - it("Should fail to generate the custom ST -- deployedAt param is 0", async() => { + it("Should fail to generate the custom ST -- deployedAt param is 0", async () => { catchRevert( - I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, "I am custom ST", 0, {from: account_polymath}), + I_STRProxied.modifySecurityToken(name2, symbol2, token_owner, dummy_token, "I am custom ST", 0, { from: account_polymath }), "tx revert -> because deployedAt param is 0" ); }); - it("Should successfully generate custom token", async() => { + it("Should successfully generate custom token", async () => { // Register the new ticker -- Fulfiling the TickerStatus.ON condition await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp }); let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); console.log(tickersListArray); - await I_STRProxied.registerTicker(account_temp, "LOG", "LOGAN", { from : account_temp }); + await I_STRProxied.registerTicker(account_temp, "LOG", "LOGAN", { from: account_temp }); tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); console.log(tickersListArray); // Generating the ST - let tx = await I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); + let tx = await I_STRProxied.modifySecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), { + from: account_polymath + }); tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); console.log(tickersListArray); assert.equal(tx.logs[1].args._ticker, "LOG", "Symbol should match with the registered symbol"); - assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token,`Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); + assert.equal( + tx.logs[1].args._securityTokenAddress, + dummy_token, + `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken` + ); let symbolDetails = await I_STRProxied.getTickerDetails("LOG"); assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); assert.equal(symbolDetails[3], "LOGAN", `Name of the symbol should be LOGAN`); }); - it("Should successfully generate the custom token", async() => { + it("Should successfully generate the custom token", async () => { // Fulfilling the TickerStatus.NN condition - // + // // await catchRevert(I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath})); // await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(10), false, {from: account_polymath}); // await increaseTime(duration.days(1)); - let tx = await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), {from: account_polymath}); + let tx = await I_STRProxied.modifySecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", latestTime(), { + from: account_polymath + }); assert.equal(tx.logs[1].args._ticker, "LOG2", "Symbol should match with the registered symbol"); - assert.equal(tx.logs[1].args._securityTokenAddress, dummy_token, `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken`); + assert.equal( + tx.logs[1].args._securityTokenAddress, + dummy_token, + `Address of the SecurityToken should be matched with the input value of addCustomSecurityToken` + ); assert.equal(tx.logs[0].args._owner, account_temp, `Token owner should be ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "LOG2", `Symbol should be LOG2`); let symbolDetails = await I_STRProxied.getTickerDetails("LOG2"); assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); assert.equal(symbolDetails[3], "LOGAN2", `Name of the symbol should be LOGAN`); }); - }); - describe("Test case for modifyTicker", async() => { - - it("Should add the custom ticker --failed because of bad owner", async() => { + describe("Test case for modifyTicker", async () => { + it("Should add the custom ticker --failed because of bad owner", async () => { catchRevert( - I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_temp}), + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), latestTime() + duration.days(10), false, { + from: account_temp + }), "tx revert -> failed beacause of bad owner0" ); - }) + }); - it("Should add the custom ticker --fail ticker length should not be 0", async() => { + it("Should add the custom ticker --fail ticker length should not be 0", async () => { catchRevert( - I_STRProxied.modifyTicker(token_owner, "", "Ether", latestTime(), (latestTime() + duration.days(10)), false, {from: account_polymath}), + I_STRProxied.modifyTicker(token_owner, "", "Ether", latestTime(), latestTime() + duration.days(10), false, { + from: account_polymath + }), "tx revert -> failed beacause ticker length should not be 0" ); - }) + }); - it("Should add the custom ticker --failed because time should not be 0", async() => { + it("Should add the custom ticker --failed because time should not be 0", async () => { catchRevert( - I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", 0, (latestTime() + duration.days(10)), false, {from: account_polymath}), + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", 0, latestTime() + duration.days(10), false, { + from: account_polymath + }), "tx revert -> failed because time should not be 0" ); - }) + }); - it("Should add the custom ticker --failed because registeration date is greater than the expiryDate", async() => { + it("Should add the custom ticker --failed because registeration date is greater than the expiryDate", async () => { catchRevert( - I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() - duration.minutes(10)), false, {from: account_polymath}), + I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), latestTime() - duration.minutes(10), false, { + from: account_polymath + }), "tx revert -> failed because registeration date is greater than the expiryDate" ); - }) + }); - it("Should add the custom ticker --failed because owner should not be 0x", async() => { + it("Should add the custom ticker --failed because owner should not be 0x", async () => { catchRevert( - I_STRProxied.modifyTicker("0x000000000000000000000000000000000000000000", "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}), + I_STRProxied.modifyTicker( + "0x000000000000000000000000000000000000000000", + "ETH", + "Ether", + latestTime(), + latestTime() + duration.minutes(10), + false, + { from: account_polymath } + ), "tx revert -> failed because owner should not be 0x" ); - }) + }); - it("Should add the new custom ticker", async() => { - let tx = await I_STRProxied.modifyTicker(account_temp, "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + it("Should add the new custom ticker", async () => { + let tx = await I_STRProxied.modifyTicker( + account_temp, + "ETH", + "Ether", + latestTime(), + latestTime() + duration.minutes(10), + false, + { from: account_polymath } + ); assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "ETH", "Should be equal to ETH"); - }) + }); - it("Should change the details of the existing ticker", async() => { - let tx = await I_STRProxied.modifyTicker(token_owner, "ETH", "Ether", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + it("Should change the details of the existing ticker", async () => { + let tx = await I_STRProxied.modifyTicker( + token_owner, + "ETH", + "Ether", + latestTime(), + latestTime() + duration.minutes(10), + false, + { from: account_polymath } + ); assert.equal(tx.logs[0].args._owner, token_owner); }); - }); - describe("Test cases for the transferTickerOwnership()", async() => { - - it("Should able to transfer the ticker ownership -- failed because token is not deployed having the same ticker", async() => { + describe("Test cases for the transferTickerOwnership()", async () => { + it("Should able to transfer the ticker ownership -- failed because token is not deployed having the same ticker", async () => { catchRevert( - I_STRProxied.transferTickerOwnership(account_issuer, "ETH", {from: account_temp}), + I_STRProxied.transferTickerOwnership(account_issuer, "ETH", { from: account_temp }), "tx revert -> failed because token is not deployed having the same ticker" - ) - }) + ); + }); - it("Should able to transfer the ticker ownership -- failed because new owner is 0x", async() => { - - await I_SecurityToken002.transferOwnership(account_temp, {from: token_owner}); + it("Should able to transfer the ticker ownership -- failed because new owner is 0x", async () => { + await I_SecurityToken002.transferOwnership(account_temp, { from: token_owner }); catchRevert( - I_STRProxied.transferTickerOwnership("0x00000000000000000000000000000000000000000", symbol2, {from: token_owner}), + I_STRProxied.transferTickerOwnership("0x00000000000000000000000000000000000000000", symbol2, { from: token_owner }), "tx revert -> failed because new owner is 0x" - ) - }) + ); + }); - it("Should able to transfer the ticker ownership -- failed because ticker is of zero length", async() => { + it("Should able to transfer the ticker ownership -- failed because ticker is of zero length", async () => { catchRevert( - I_STRProxied.transferTickerOwnership(account_temp, "", {from: token_owner}), + I_STRProxied.transferTickerOwnership(account_temp, "", { from: token_owner }), "tx revert -> failed because ticker is of zero length" ); - }) + }); - it("Should able to transfer the ticker ownership", async() => { - let tx = await I_STRProxied.transferTickerOwnership(account_temp, symbol2, {from: token_owner, gas: 5000000 }); + it("Should able to transfer the ticker ownership", async () => { + let tx = await I_STRProxied.transferTickerOwnership(account_temp, symbol2, { from: token_owner, gas: 5000000 }); assert.equal(tx.logs[0].args._newOwner, account_temp); let symbolDetails = await I_STRProxied.getTickerDetails.call(symbol2); assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); assert.equal(symbolDetails[3], name2, `Name of the symbol should be ${name2}`); - }) - }) - - describe("Test case for the changeSecurityLaunchFee()", async() => { + }); + }); - it("Should able to change the STLaunchFee-- failed because of bad owner", async() => { - catchRevert( - I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_temp}), + describe("Test case for the changeSecurityLaunchFee()", async () => { + it("Should able to change the STLaunchFee-- failed because of bad owner", async () => { + catchRevert( + I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), { from: account_temp }), "tx revert -> failed because of bad owner" - ); + ); }); - it("Should able to change the STLaunchFee-- failed because of putting the same fee", async() => { + it("Should able to change the STLaunchFee-- failed because of putting the same fee", async () => { catchRevert( - I_STRProxied.changeSecurityLaunchFee(initRegFee, {from: account_polymath}), + I_STRProxied.changeSecurityLaunchFee(initRegFee, { from: account_polymath }), "tx revert -> failed because of putting the same fee" - ) + ); }); - it("Should able to change the STLaunchFee", async() => { - let tx = await I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), {from: account_polymath}); + it("Should able to change the STLaunchFee", async () => { + let tx = await I_STRProxied.changeSecurityLaunchFee(web3.utils.toWei("500"), { from: account_polymath }); assert.equal(tx.logs[0].args._newFee, web3.utils.toWei("500")); let stLaunchFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3("stLaunchFee")); assert.equal(stLaunchFee, web3.utils.toWei("500")); }); + }); - }) - - describe("Test cases for the changeExpiryLimit()", async() => { - - it("Should able to change the ExpiryLimit-- failed because of bad owner", async() => { - catchRevert( - I_STRProxied.changeExpiryLimit(duration.days(15), {from: account_temp}), + describe("Test cases for the changeExpiryLimit()", async () => { + it("Should able to change the ExpiryLimit-- failed because of bad owner", async () => { + catchRevert( + I_STRProxied.changeExpiryLimit(duration.days(15), { from: account_temp }), "tx revert -> failed because of bad owner" - ) + ); }); - it("Should able to change the ExpiryLimit-- failed because expirylimit is less than 1 day", async() => { + it("Should able to change the ExpiryLimit-- failed because expirylimit is less than 1 day", async () => { catchRevert( - I_STRProxied.changeExpiryLimit(duration.minutes(50), {from: account_polymath}), + I_STRProxied.changeExpiryLimit(duration.minutes(50), { from: account_polymath }), "tx revert -> failed because expirylimit is less than 1 day" ); }); - it("Should able to change the ExpiryLimit", async() => { - let tx = await I_STRProxied.changeExpiryLimit(duration.days(20), {from: account_polymath}); + it("Should able to change the ExpiryLimit", async () => { + let tx = await I_STRProxied.changeExpiryLimit(duration.days(20), { from: account_polymath }); assert.equal(tx.logs[0].args._newExpiry, duration.days(20)); let expiry = await I_STRProxied.getUintValues(web3.utils.soliditySha3("expiryLimit")); assert.equal(expiry, duration.days(20)); }); - }) - - describe("Test cases for the changeTickerRegistrationFee()", async() => { + }); - it("Should able to change the TickerRegFee-- failed because of bad owner", async() => { + describe("Test cases for the changeTickerRegistrationFee()", async () => { + it("Should able to change the TickerRegFee-- failed because of bad owner", async () => { catchRevert( - I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("500"), {from: account_temp}), + I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("500"), { from: account_temp }), "tx revert -> failed because of bad owner" - ) + ); }); - it("Should able to change the TickerRegFee-- failed because of putting the same fee", async() => { - catchRevert( - I_STRProxied.changeTickerRegistrationFee(initRegFee, {from: account_polymath}), + it("Should able to change the TickerRegFee-- failed because of putting the same fee", async () => { + catchRevert( + I_STRProxied.changeTickerRegistrationFee(initRegFee, { from: account_polymath }), "tx revert -> failed because of putting the same fee" - ); + ); }); - it("Should able to change the TickerRegFee", async() => { - let tx = await I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("400"), {from: account_polymath}); + it("Should able to change the TickerRegFee", async () => { + let tx = await I_STRProxied.changeTickerRegistrationFee(web3.utils.toWei("400"), { from: account_polymath }); assert.equal(tx.logs[0].args._newFee, web3.utils.toWei("400")); let tickerRegFee = await I_STRProxied.getUintValues(web3.utils.soliditySha3("tickerRegFee")); assert.equal(tickerRegFee, web3.utils.toWei("400")); }); it("Should fail to register the ticker with the old fee", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); catchRevert( - I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }), + I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from: token_owner }), "tx revert -> failed because of ticker registeration fee gets change" ); - }) + }); - it("Should register the ticker with the new fee", async() => { + it("Should register the ticker with the new fee", async () => { await I_PolyToken.getTokens(web3.utils.toWei("1000"), token_owner); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from : token_owner }); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, "POLY", "Polymath", { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner, `Token owner should be ${token_owner}`); assert.equal(tx.logs[0].args._ticker, "POLY", `Symbol should be POLY`); }); - it("Should fail to launch the securityToken with the old launch fee", async() => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + it("Should fail to launch the securityToken with the old launch fee", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); catchRevert( I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }), "tx revert -> failed because of old launch fee" - ) - }) + ); + }); - it("Should launch the the securityToken", async() => { - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner}); + it("Should launch the the securityToken", async () => { + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner }); let tx = await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token @@ -905,80 +977,75 @@ contract('SecurityTokenRegistry', accounts => { }); }); - describe("Test case for the update poly token", async() => { - - it("Should change the polytoken address -- failed because of bad owner", async() => { + describe("Test case for the update poly token", async () => { + it("Should change the polytoken address -- failed because of bad owner", async () => { catchRevert( - I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_temp}), + I_STRProxied.updatePolyTokenAddress(dummy_token, { from: account_temp }), "tx revert -> failed because of bad owner" ); - }) + }); - it("Should change the polytoken address -- failed because of 0x address", async() => { - catchRevert( - I_STRProxied.updatePolyTokenAddress("0x0000000000000000000000000000000000000000000", {from: account_polymath}), + it("Should change the polytoken address -- failed because of 0x address", async () => { + catchRevert( + I_STRProxied.updatePolyTokenAddress("0x0000000000000000000000000000000000000000000", { from: account_polymath }), "tx revert -> failed because 0x address" - ); - }) + ); + }); - it("Should successfully change the polytoken address", async() => { + it("Should successfully change the polytoken address", async () => { let _id = await takeSnapshot(); - await I_STRProxied.updatePolyTokenAddress(dummy_token, {from: account_polymath}); + await I_STRProxied.updatePolyTokenAddress(dummy_token, { from: account_polymath }); assert.equal(await I_STRProxied.getAddressValues.call(web3.utils.soliditySha3("polyToken")), dummy_token); await revertToSnapshot(_id); }); - }) - - describe("Test cases for getters", async() => { + }); - it("Should get the security token address", async() => { - let address = await I_STRProxied.getSecurityTokenAddress.call(symbol); - assert.equal(address, I_SecurityToken.address); + describe("Test cases for getters", async () => { + it("Should get the security token address", async () => { + let address = await I_STRProxied.getSecurityTokenAddress.call(symbol); + assert.equal(address, I_SecurityToken.address); }); - it("Should get the security token data", async() => { + it("Should get the security token data", async () => { let data = await I_STRProxied.getSecurityTokenData.call(I_SecurityToken.address); assert.equal(data[0], symbol); assert.equal(data[1], token_owner); }); - it("Should get the tickers by owner", async() => { + it("Should get the tickers by owner", async () => { let tickersList = await I_STRProxied.getTickersByOwner.call(token_owner); assert.equal(tickersList.length, 4); let tickersListArray = await I_STRProxied.getTickersByOwner.call(account_temp); console.log(tickersListArray); assert.equal(tickersListArray.length, 3); }); - }); - describe("Test case for the Removing the ticker", async() => { - - it("Should remove the ticker from the polymath ecosystem -- bad owner", async() => { + describe("Test case for the Removing the ticker", async () => { + it("Should remove the ticker from the polymath ecosystem -- bad owner", async () => { catchRevert( - I_STRProxied.removeTicker(symbol2, {from: account_investor1}), + I_STRProxied.removeTicker(symbol2, { from: account_investor1 }), "tx revert -> failed because msg.sender should be account_polymath" - ) - }) + ); + }); - it("Should remove the ticker from the polymath ecosystem -- fail because ticker doesn't exist in the ecosystem", async() => { + it("Should remove the ticker from the polymath ecosystem -- fail because ticker doesn't exist in the ecosystem", async () => { catchRevert( - I_STRProxied.removeTicker("HOLA", {from: account_polymath}), + I_STRProxied.removeTicker("HOLA", { from: account_polymath }), "tx revert -> failed because ticker doesn't exist in the polymath ecosystem" - ) - }) + ); + }); - it("Should successfully remove the ticker from the polymath ecosystem", async() => { - let tx = await I_STRProxied.removeTicker(symbol2, {from: account_polymath}); + it("Should successfully remove the ticker from the polymath ecosystem", async () => { + let tx = await I_STRProxied.removeTicker(symbol2, { from: account_polymath }); assert.equal(tx.logs[0].args._ticker, symbol2, "Ticker doesn't get deleted successfully"); }); - }) - - describe(" Test cases of the registerTicker", async() => { + }); + describe(" Test cases of the registerTicker", async () => { it("Should register the ticker 1", async () => { await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp }); let tx = await I_STRProxied.registerTicker(account_temp, "TOK1", "", { from: account_temp }); assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK1", `Symbol should be TOK1`); @@ -987,7 +1054,7 @@ contract('SecurityTokenRegistry', accounts => { it("Should register the ticker 2", async () => { await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp }); let tx = await I_STRProxied.registerTicker(account_temp, "TOK2", "", { from: account_temp }); assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK2", `Symbol should be TOK2`); @@ -996,80 +1063,85 @@ contract('SecurityTokenRegistry', accounts => { it("Should register the ticker 3", async () => { await I_PolyToken.getTokens(web3.utils.toWei("1000"), account_temp); - await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp}); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("1000"), { from: account_temp }); let tx = await I_STRProxied.registerTicker(account_temp, "TOK3", "", { from: account_temp }); assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK3", `Symbol should be TOK3`); console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); - it("Should successfully remove the ticker 2", async() => { - let tx = await I_STRProxied.removeTicker("TOK2", {from: account_polymath}); + it("Should successfully remove the ticker 2", async () => { + let tx = await I_STRProxied.removeTicker("TOK2", { from: account_polymath }); assert.equal(tx.logs[0].args._ticker, "TOK2", "Ticker doesn't get deleted successfully"); console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); }); - it("Should modify ticker 1", async() => { - let tx = await I_STRProxied.modifyTicker(account_temp, "TOK1", "TOKEN 1", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + it("Should modify ticker 1", async () => { + let tx = await I_STRProxied.modifyTicker( + account_temp, + "TOK1", + "TOKEN 1", + latestTime(), + latestTime() + duration.minutes(10), + false, + { from: account_polymath } + ); assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK1", "Should be equal to TOK1"); assert.equal(tx.logs[0].args._name, "TOKEN 1", "Should be equal to TOKEN 1"); console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }) + }); - it("Should modify ticker 3", async() => { - let tx = await I_STRProxied.modifyTicker(account_temp, "TOK3", "TOKEN 3", latestTime(), (latestTime() + duration.minutes(10)), false, {from: account_polymath}); + it("Should modify ticker 3", async () => { + let tx = await I_STRProxied.modifyTicker( + account_temp, + "TOK3", + "TOKEN 3", + latestTime(), + latestTime() + duration.minutes(10), + false, + { from: account_polymath } + ); assert.equal(tx.logs[0].args._owner, account_temp, `Should be equal to the ${account_temp}`); assert.equal(tx.logs[0].args._ticker, "TOK3", "Should be equal to TOK3"); assert.equal(tx.logs[0].args._name, "TOKEN 3", "Should be equal to TOKEN 3"); console.log((await I_STRProxied.getTickersByOwner.call(account_temp)).map(x => web3.utils.toUtf8(x))); - }) - + }); }); - describe("Test cases for IRegistry functionality", async() => { - - describe("Test cases for reclaiming funds", async() => { - - it("Should successfully reclaim POLY tokens", async() => { + describe("Test cases for IRegistry functionality", async () => { + describe("Test cases for reclaiming funds", async () => { + it("Should successfully reclaim POLY tokens", async () => { I_PolyToken.transfer(I_STRProxied.address, web3.utils.toWei("1"), { from: token_owner }); let bal1 = await I_PolyToken.balanceOf.call(account_polymath); await I_STRProxied.reclaimERC20(I_PolyToken.address); let bal2 = await I_PolyToken.balanceOf.call(account_polymath); - assert.isAtLeast(bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), bal2.dividedBy(new BigNumber(10).pow(18)).toNumber()); + assert.isAtLeast( + bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), + bal2.dividedBy(new BigNumber(10).pow(18)).toNumber() + ); }); - }); - describe("Test cases for pausing the contract", async() => { - - it("Should fail to pause if msg.sender is not owner", async() => { - catchRevert( - I_STRProxied.pause({ from: account_temp }), - "tx revert -> msg.sender should be account_polymath" - ) + describe("Test cases for pausing the contract", async () => { + it("Should fail to pause if msg.sender is not owner", async () => { + catchRevert(I_STRProxied.pause({ from: account_temp }), "tx revert -> msg.sender should be account_polymath"); }); - it("Should successfully pause the contract", async() => { + it("Should successfully pause the contract", async () => { await I_STRProxied.pause({ from: account_polymath }); let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); assert.isOk(status); }); - it("Should fail to unpause if msg.sender is not owner", async() => { - catchRevert( - I_STRProxied.unpause({ from: account_temp }), - "tx revert -> msg.sender should be account_polymath" - ) + it("Should fail to unpause if msg.sender is not owner", async () => { + catchRevert(I_STRProxied.unpause({ from: account_temp }), "tx revert -> msg.sender should be account_polymath"); }); - it("Should successfully unpause the contract", async() => { + it("Should successfully unpause the contract", async () => { await I_STRProxied.unpause({ from: account_polymath }); let status = await I_STRProxied.getBoolValues.call(web3.utils.soliditySha3("paused")); assert.isNotOk(status); }); - }); - }); - }); diff --git a/test/o_security_token.js b/test/o_security_token.js index 2ba70297b..16d507053 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -1,33 +1,30 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); -const CappedSTO = artifacts.require('./CappedSTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - - -contract('SecurityToken', accounts => { - - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); +const CappedSTO = artifacts.require("./CappedSTO.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("SecurityToken", accounts => { // Accounts Variable declaration let account_polymath; let account_investor1; @@ -88,8 +85,8 @@ contract('SecurityToken', accounts => { // delagate details const delegateDetails = "I am delegate .."; - const TM_Perm = 'FLAGS'; - const TM_Perm_Whitelist = 'WHITELIST'; + const TM_Perm = "FLAGS"; + const TM_Perm_Whitelist = "WHITELIST"; // Capped STO details let startTime; @@ -97,14 +94,13 @@ contract('SecurityToken', accounts => { const cap = web3.utils.toWei("10000"); const rate = 1000; const fundRaiseType = [0]; - const cappedSTOSetupCost= web3.utils.toWei("20000","ether"); + const cappedSTOSetupCost = web3.utils.toWei("20000", "ether"); const maxCost = cappedSTOSetupCost; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - before(async() => { + const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -120,35 +116,33 @@ contract('SecurityToken', accounts => { token_owner = account_issuer; account_controller = account_temp; - // ----------- POLYMATH NETWORK Configuration ------------ + // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 4 (a): Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -158,7 +152,9 @@ contract('SecurityToken', accounts => { // STEP 4 (b): Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -170,58 +166,58 @@ contract('SecurityToken', accounts => { I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - address_zero, - "CappedSTOFactory contract was not deployed" - ); + assert.notEqual(I_CappedSTOFactory.address.valueOf(), address_zero, "CappedSTOFactory contract was not deployed"); // STEP 5: Register the Modules with the ModuleRegistry contract - // Step 6: Deploy the STFactory contract + // Step 6: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - // Step 7: Deploy the SecurityTokenRegistry contract + // Step 7: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` @@ -242,11 +238,10 @@ contract('SecurityToken', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol); }); @@ -260,116 +255,106 @@ contract('SecurityToken', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not console.log(log.args); assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal(web3.utils.toUtf8(log.args._name),"GeneralTransferManager"); + assert.equal(web3.utils.toUtf8(log.args._name), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - assert.notEqual( - I_GeneralTransferManager.address.valueOf(), - address_zero, - "GeneralTransferManager contract was not deployed", - ); - + assert.notEqual(I_GeneralTransferManager.address.valueOf(), address_zero, "GeneralTransferManager contract was not deployed"); }); - it("Should mint the tokens before attaching the STO -- fail only be called by the owner", async() => { - + it("Should mint the tokens before attaching the STO -- fail only be called by the owner", async () => { let fromTime = latestTime(); let toTime = fromTime + duration.days(100); let expiryTime = toTime + duration.days(100); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_affiliate1, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 6000000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_affiliate1, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 6000000 + }); assert.equal(tx.logs[0].args._investor, account_affiliate1, "Failed in adding the investor in whitelist"); - await catchRevert(I_SecurityToken.mint(account_investor1, (100 * Math.pow(10, 18)), {from: account_delegate})); + await catchRevert(I_SecurityToken.mint(account_investor1, 100 * Math.pow(10, 18), { from: account_delegate })); }); - it("Should mint the tokens before attaching the STO", async() => { - await I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + it("Should mint the tokens before attaching the STO", 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(), 100); }); - it("Should mint the multi tokens before attaching the STO -- fail only be called by the owner", async() => { - + it("Should mint the multi tokens before attaching the STO -- fail only be called by the owner", async () => { let fromTime = latestTime(); let toTime = fromTime + duration.days(100); let expiryTime = toTime + duration.days(100); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_affiliate2, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 6000000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_affiliate2, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 6000000 + }); assert.equal(tx.logs[0].args._investor, account_affiliate2, "Failed in adding the investor in whitelist"); - await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18)), (110 * Math.pow(10, 18))], {from: account_delegate, gas: 500000})); + await catchRevert( + I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [100 * Math.pow(10, 18), 110 * Math.pow(10, 18)], { + from: account_delegate, + gas: 500000 + }) + ); }); - it("Should mintMulti", async() => { - - await catchRevert(I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18))], {from: token_owner, gas: 500000})); - }) + it("Should mintMulti", async () => { + await catchRevert( + I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [100 * Math.pow(10, 18)], { + from: token_owner, + gas: 500000 + }) + ); + }); - it("Should mint the tokens for multiple afiliated investors before attaching the STO", async() => { - await I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18)), (110 * Math.pow(10, 18))], {from: token_owner, gas: 500000}); + it("Should mint the tokens for multiple afiliated investors before attaching the STO", 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(), 200); let balance2 = await I_SecurityToken.balanceOf(account_affiliate2); assert.equal(balance2.dividedBy(new BigNumber(10).pow(18)).toNumber(), 110); }); - it("Should finish the minting -- fail because feature is not activated", async() => { - - await catchRevert(I_SecurityToken.freezeMinting({from: token_owner})); + it("Should finish the minting -- fail because feature is not activated", async () => { + await catchRevert(I_SecurityToken.freezeMinting({ from: token_owner })); }); - it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async() => { - - await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: token_owner})); + it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async () => { + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, { from: token_owner })); }); - it("Should finish the minting -- successfully activate the feature", async() => { - await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", false, {from: account_polymath})); + it("Should finish the minting -- successfully activate the feature", async () => { + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", false, { from: account_polymath })); - 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})); + 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 })); - await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_polymath})); + await catchRevert(I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, { from: account_polymath })); }); - it("Should finish the minting -- fail because msg.sender is not the owner", async() => { - - await catchRevert(I_SecurityToken.freezeMinting({from: account_temp})); + it("Should finish the minting -- fail because msg.sender is not the owner", async () => { + await catchRevert(I_SecurityToken.freezeMinting({ from: account_temp })); }); - it("Should finish minting & restrict the further minting", async() => { + it("Should finish minting & restrict the further minting", async () => { let id = await takeSnapshot(); - await I_SecurityToken.freezeMinting({from: token_owner}); - - await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); + await I_SecurityToken.freezeMinting({ from: token_owner }); + + await catchRevert(I_SecurityToken.mint(account_affiliate1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); await revertToSnapshot(id); }); @@ -377,7 +362,7 @@ contract('SecurityToken', accounts => { startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); @@ -386,9 +371,11 @@ contract('SecurityToken', accounts => { 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}); - - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, { from: token_owner })); + await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: token_owner }); + + await catchRevert( + I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000", "ether"), 0, { from: token_owner }) + ); }); it("Should successfully attach the STO factory with the security token", async () => { @@ -397,7 +384,7 @@ contract('SecurityToken', accounts => { 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}); + 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 }); @@ -407,25 +394,24 @@ contract('SecurityToken', accounts => { }); 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}); + 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}); - - await catchRevert(I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); + await I_SecurityToken.freezeMinting({ from: token_owner }); + + await catchRevert(I_SecurityToken.mint(account_affiliate1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); await revertToSnapshot(id); }); - }); - describe("Module related functions", async() => { + describe("Module related functions", async () => { it("Should get the modules of the securityToken by index", async () => { let moduleData = await I_SecurityToken.getModule.call(I_CappedSTO.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "CappedSTO"); + 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); @@ -434,7 +420,7 @@ contract('SecurityToken', accounts => { it("Should get the modules of the securityToken by index (not added into the security token yet)", async () => { let moduleData = await I_SecurityToken.getModule.call(token_owner); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), ""); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ""), ""); assert.equal(moduleData[1], address_zero); }); @@ -442,7 +428,7 @@ contract('SecurityToken', accounts => { let moduleList = await I_SecurityToken.getModulesByName.call("CappedSTO"); assert.isTrue(moduleList.length == 1, "Only one STO"); let moduleData = await I_SecurityToken.getModule.call(moduleList[0]); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "CappedSTO"); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ""), "CappedSTO"); assert.equal(moduleData[1], I_CappedSTO.address); }); @@ -456,53 +442,48 @@ contract('SecurityToken', accounts => { assert.isTrue(moduleData.length == 0, "No Permission Manager"); }); - it("Should fail in updating the token details", async() => { - - await catchRevert(I_SecurityToken.updateTokenDetails("new token details", {from: account_delegate})); + it("Should fail in updating the token details", async () => { + await catchRevert(I_SecurityToken.updateTokenDetails("new token details", { from: account_delegate })); }); - it("Should update the token details", async() => { - let log = await I_SecurityToken.updateTokenDetails("new token details", {from: token_owner}); + it("Should update the token details", async () => { + let log = await I_SecurityToken.updateTokenDetails("new token details", { from: token_owner }); assert.equal(log.logs[0].args._newDetails, "new token details"); }); - it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async() => { - - await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner })); + it("Should successfully remove the general transfer manager module from the securityToken -- fails msg.sender should be Owner", async () => { + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: token_owner })); }); - it("Should fail to remove the module - module not archived", async() => { - - await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : account_temp })); - }) + it("Should fail to remove the module - module not archived", async () => { + await catchRevert(I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: account_temp })); + }); - it("Should fail to remove the module - incorrect address", async() => { - - await catchRevert(I_SecurityToken.removeModule(0, { from : token_owner })); - }) + it("Should fail to remove the module - incorrect address", async () => { + await catchRevert(I_SecurityToken.removeModule(0, { from: token_owner })); + }); - it("Should successfully remove the general transfer manager module from the securityToken", async() => { + it("Should successfully remove the general transfer manager module from the securityToken", async () => { let key = await takeSnapshot(); - await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); - let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from : token_owner }); + await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }); + let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: token_owner }); assert.equal(tx.logs[0].args._types[0], transferManagerKey); assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); await revertToSnapshot(key); }); - it("Should verify the revertion of snapshot works properly", async() => { + it("Should verify the revertion of snapshot works properly", async () => { let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ""), "GeneralTransferManager"); assert.equal(moduleData[1], I_GeneralTransferManager.address); }); - - it("Should successfully archive the general transfer manager module from the securityToken", async() => { - let tx = await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from : token_owner }); + it("Should successfully archive the general transfer manager module from the securityToken", async () => { + let tx = await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }); assert.equal(tx.logs[0].args._types[0], transferManagerKey); assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ""), "GeneralTransferManager"); assert.equal(moduleData[1], I_GeneralTransferManager.address); assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); assert.equal(moduleData[3], true); @@ -510,582 +491,544 @@ contract('SecurityToken', accounts => { it("Should successfully mint tokens while GTM archived", async () => { let key = await takeSnapshot(); - await I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + await I_SecurityToken.mint(1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 }); let balance = await I_SecurityToken.balanceOf(1); assert.equal(balance.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); await revertToSnapshot(key); }); - it("Should successfully unarchive the general transfer manager module from the securityToken", async() => { - let tx = await I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from : token_owner }); + it("Should successfully unarchive the general transfer manager module from the securityToken", async () => { + let tx = await I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from: token_owner }); assert.equal(tx.logs[0].args._types[0], transferManagerKey); assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); let moduleData = await I_SecurityToken.getModule.call(I_GeneralTransferManager.address); - assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ''), "GeneralTransferManager"); + assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ""), "GeneralTransferManager"); assert.equal(moduleData[1], I_GeneralTransferManager.address); assert.equal(moduleData[2], I_GeneralTransferManagerFactory.address); assert.equal(moduleData[3], false); }); it("Should fail to mint tokens while GTM unarchived", async () => { - - await catchRevert(I_SecurityToken.mint(1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000})); + await catchRevert(I_SecurityToken.mint(1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); + }); + it("Should change the budget of the module - fail incorrect address", async () => { + await catchRevert(I_SecurityToken.changeModuleBudget(0, 100 * Math.pow(10, 18), { from: token_owner })); }); - it("Should change the budget of the module - fail incorrect address", async() => { - - await catchRevert(I_SecurityToken.changeModuleBudget(0, (100 * Math.pow(10, 18)),{ from : token_owner})); - }); + it("Should change the budget of the module", async () => { + let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, 100 * Math.pow(10, 18), { from: token_owner }); + assert.equal(tx.logs[1].args._moduleTypes[0], stoKey); + assert.equal(tx.logs[1].args._module, I_CappedSTO.address); + assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); + }); + }); + describe("General Transfer manager Related test cases", async () => { + it("Should Buy the tokens", async () => { + balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); + // Add the Investor in to the whitelist - it("Should change the budget of the module", async() => { - let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, (100 * Math.pow(10, 18)),{ from : token_owner}); - assert.equal(tx.logs[1].args._moduleTypes[0], stoKey); - assert.equal(tx.logs[1].args._module, I_CappedSTO.address); - assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); - }); + fromTime = latestTime(); + toTime = fromTime + duration.days(100); + expiryTime = toTime + duration.days(100); - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 6000000 + }); + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); + // Jump time + await increaseTime(5000); + // Fallback transaction + console.log("BEFORE"); + await web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei("1", "ether") + }); + console.log("AFTER"); + assert.equal((await I_CappedSTO.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - describe("General Transfer manager Related test cases", async () => { + assert.equal(await I_CappedSTO.investorCount.call(), 1); - it("Should Buy the tokens", async() => { - balanceOfReceiver = await web3.eth.getBalance(account_fundsReceiver); - // Add the Investor in to the whitelist - - fromTime = latestTime(); - toTime = fromTime + duration.days(100); - expiryTime = toTime + duration.days(100); - - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 6000000 - }); - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); - // Jump time - await increaseTime(5000); - // Fallback transaction - console.log("BEFORE"); - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - }); - console.log("AFTER"); - assert.equal( - (await I_CappedSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1 - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); - assert.equal(await I_CappedSTO.investorCount.call(), 1); + it("Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2", async () => { + await catchRevert(I_SecurityToken.transfer(account_investor2, 10 * Math.pow(10, 18), { from: account_investor1 })); + }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }); + it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { + // Add permission to the deletgate (A regesteration process) + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, { from: token_owner }); + let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; + I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); + await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); + }); - it("Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2", async() => { - - await catchRevert(I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1})); + it("Should provide the permission to the delegate to change the transfer bools", async () => { + // Add permission to the deletgate (A regesteration process) + await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { + from: token_owner }); - it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { - - // Add permission to the deletgate (A regesteration process) - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: token_owner}); - let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; - I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); - }); + assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); + }); - it("Should provide the permission to the delegate to change the transfer bools", async () => { - // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner}); - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: token_owner }); + it("Should fail to activate the bool allowAllTransfer", async () => { + await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from: account_temp })); + }); - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm)); - }); + it("Should activate the bool allowAllTransfer", async () => { + ID_snap = await takeSnapshot(); + let tx = await I_GeneralTransferManager.changeAllowAllTransfers(true, { from: account_delegate }); + assert.isTrue(tx.logs[0].args._allowAllTransfers, "AllowTransfer variable is not successfully updated"); + }); - it("Should fail to activate the bool allowAllTransfer", async() => { - - await catchRevert(I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_temp })); - }); + it("Should fail to send tokens with the wrong granularity", async () => { + await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from: account_investor1 })); + }); - it("Should activate the bool allowAllTransfer", async() => { - ID_snap = await takeSnapshot(); - let tx = await I_GeneralTransferManager.changeAllowAllTransfers(true, { from : account_delegate }); + it("Should adjust granularity", async () => { + await catchRevert(I_SecurityToken.changeGranularity(0, { from: token_owner })); + }); - assert.isTrue(tx.logs[0].args._allowAllTransfers, "AllowTransfer variable is not successfully updated"); - }); + it("Should adjust granularity", async () => { + await I_SecurityToken.changeGranularity(Math.pow(10, 17), { from: token_owner }); + await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from: account_investor1, gas: 2500000 }); + await I_SecurityToken.transfer(account_investor1, Math.pow(10, 17), { from: accounts[7], gas: 2500000 }); + }); + it("Should transfer from whitelist investor to non-whitelist investor in first tx and in 2nd tx non-whitelist to non-whitelist transfer", async () => { + await I_SecurityToken.transfer(accounts[7], 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 }); - it("Should fail to send tokens with the wrong granularity", async() => { - - await catchRevert(I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1})); - }); + assert.equal( + (await I_SecurityToken.balanceOf(accounts[7])).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 10, + "Transfer doesn't take place properly" + ); - it("Should adjust granularity", async() => { - - await catchRevert(I_SecurityToken.changeGranularity(0, {from: token_owner })); - }); + await I_SecurityToken.transfer(account_temp, 5 * Math.pow(10, 18), { from: accounts[7], gas: 2500000 }); - it("Should adjust granularity", async() => { - - await I_SecurityToken.changeGranularity(Math.pow(10, 17), {from: token_owner }); - await I_SecurityToken.transfer(accounts[7], Math.pow(10, 17), { from : account_investor1, gas: 2500000 }); - await I_SecurityToken.transfer(account_investor1, Math.pow(10, 17), { from : accounts[7], gas: 2500000}); - }); + assert.equal( + (await I_SecurityToken.balanceOf(account_temp)).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 5, + "Transfer doesn't take place properly" + ); + await revertToSnapshot(ID_snap); + }); - it("Should transfer from whitelist investor to non-whitelist investor in first tx and in 2nd tx non-whitelist to non-whitelist transfer", async() => { - await I_SecurityToken.transfer(accounts[7], (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000}); - - assert.equal( - (await I_SecurityToken.balanceOf(accounts[7])) - .dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10, - "Transfer doesn't take place properly" - ); - - await I_SecurityToken.transfer(account_temp, (5 * Math.pow(10, 18)), { from : accounts[7], gas: 2500000}); - - assert.equal( - (await I_SecurityToken.balanceOf(account_temp)) - .dividedBy(new BigNumber(10).pow(18)).toNumber(), - 5, - "Transfer doesn't take place properly" - ); - await revertToSnapshot(ID_snap); - }); + it("Should bool allowAllTransfer value is false", async () => { + assert.isFalse(await I_GeneralTransferManager.allowAllTransfers.call(), "reverting of snapshot doesn't works properly"); + }); - it("Should bool allowAllTransfer value is false", async() => { - assert.isFalse(await I_GeneralTransferManager.allowAllTransfers.call(), "reverting of snapshot doesn't works properly"); - }); + it("Should change the bool allowAllWhitelistTransfers to true", async () => { + ID_snap = await takeSnapshot(); + let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from: account_delegate }); - it("Should change the bool allowAllWhitelistTransfers to true", async () => { - ID_snap = await takeSnapshot(); - let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from : account_delegate }); + assert.isTrue(tx.logs[0].args._allowAllWhitelistTransfers, "allowAllWhitelistTransfers variable is not successfully updated"); + }); - assert.isTrue(tx.logs[0].args._allowAllWhitelistTransfers, "allowAllWhitelistTransfers variable is not successfully updated"); + it("Should transfer from whitelist investor1 to whitelist investor 2", async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor2, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 500000 }); - it("Should transfer from whitelist investor1 to whitelist investor 2", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - - await I_SecurityToken.transfer(account_investor2, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000}); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)) - .dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10, - "Transfer doesn't take place properly" - ); - }); + assert.equal(tx.logs[0].args._investor, account_investor2, "Failed in adding the investor in whitelist"); - it("Should transfer from whitelist investor1 to whitelist investor 2 -- value = 0", async() => { - let tx = await I_SecurityToken.transfer(account_investor2, 0, { from : account_investor1, gas: 2500000}); - assert.equal((tx.logs[0].args.value).toNumber(),0); - }); + await I_SecurityToken.transfer(account_investor2, 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 }); + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), + 10, + "Transfer doesn't take place properly" + ); + }); - it("Should transferFrom from one investor to other", async() => { - await I_SecurityToken.approve(account_investor1, (2 * Math.pow(10, 18)),{from: account_investor2}); - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor3, - fromTime, - toTime, - expiryTime, - true, - { - from: token_owner, - gas: 500000 - }); - - assert.equal(tx.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); - let log = await I_SecurityToken.transferFrom(account_investor2, account_investor3, (2 * Math.pow(10, 18)), {from: account_investor1}); - assert.equal((log.logs[0].args.value).toNumber(), (2 * Math.pow(10, 18))); + it("Should transfer from whitelist investor1 to whitelist investor 2 -- value = 0", async () => { + let tx = await I_SecurityToken.transfer(account_investor2, 0, { from: account_investor1, gas: 2500000 }); + assert.equal(tx.logs[0].args.value.toNumber(), 0); + }); + + it("Should transferFrom from one investor to other", async () => { + await I_SecurityToken.approve(account_investor1, 2 * Math.pow(10, 18), { from: account_investor2 }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor3, fromTime, toTime, expiryTime, true, { + from: token_owner, + gas: 500000 }); - it("Should Fail in trasferring from whitelist investor1 to non-whitelist investor", async() => { - - await catchRevert(I_SecurityToken.transfer(account_temp, (10 * Math.pow(10, 18)), { from : account_investor1, gas: 2500000})); - await revertToSnapshot(ID_snap); + assert.equal(tx.logs[0].args._investor, account_investor3, "Failed in adding the investor in whitelist"); + let log = await I_SecurityToken.transferFrom(account_investor2, account_investor3, 2 * Math.pow(10, 18), { + from: account_investor1 }); + assert.equal(log.logs[0].args.value.toNumber(), 2 * Math.pow(10, 18)); + }); - 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 trasferring from whitelist investor1 to non-whitelist investor", async () => { + await catchRevert(I_SecurityToken.transfer(account_temp, 10 * Math.pow(10, 18), { from: account_investor1, gas: 2500000 })); + await revertToSnapshot(ID_snap); + }); + + 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 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 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 () => { + // Providing the permission to the delegate + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist, true, { + from: token_owner }); - it("Should provide more permissions to the delegate", async() => { - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist, true, { from: token_owner }); + assert.isTrue( + await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist) + ); + }); - assert.isTrue(await I_GeneralPermissionManager.checkPermission(account_delegate, I_GeneralTransferManager.address, TM_Perm_Whitelist)); + it("Should add the investor in the whitelist by the delegate", async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, fromTime, toTime, expiryTime, true, { + from: account_delegate, + gas: 6000000 }); - it("Should add the investor in the whitelist by the delegate", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - fromTime, - toTime, - expiryTime, - true, - { - from: account_delegate, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); + assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); + }); + + it("should account_temp successfully buy the token", async () => { + // Fallback transaction + await web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei("1", "ether") }); - it("should account_temp successfully buy the token", async() => { - // 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.getRaised.call(0)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 2); - assert.equal( - (await I_CappedSTO.getRaised.call(0)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 2 - ); + assert.equal(await I_CappedSTO.investorCount.call(), 2); - assert.equal(await I_CappedSTO.investorCount.call(), 2); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), - 1000 - ); - }); + it("STO should fail to mint tokens after minting is frozen", async () => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({ from: token_owner }); - it("STO should fail to mint tokens after minting is frozen", async() => { - let id = await takeSnapshot(); - await I_SecurityToken.freezeMinting({from: token_owner}); - - await catchRevert(web3.eth.sendTransaction({ - from: account_temp, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); - await revertToSnapshot(id); - }); + await catchRevert( + web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei("1", "ether") + }) + ); + await revertToSnapshot(id); + }); - it("Should remove investor from the whitelist by the delegate", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - 0, - 0, - 0, - true, - { - from: account_delegate, - gas: 6000000 - }); - - assert.equal(tx.logs[0].args._investor, account_temp, "Failed in removing the investor from whitelist"); + it("Should remove investor from the whitelist by the delegate", async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, 0, 0, 0, true, { + from: account_delegate, + gas: 6000000 }); - it("should account_temp fail in buying the token", async() => { - - await catchRevert(web3.eth.sendTransaction({ + assert.equal(tx.logs[0].args._investor, account_temp, "Failed in removing the investor from whitelist"); + }); + + it("should account_temp fail in buying the token", async () => { + await catchRevert( + web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); - }); + value: web3.utils.toWei("1", "ether") + }) + ); + }); - it("Should freeze the transfers", async() => { - let tx = await I_SecurityToken.freezeTransfers({from: token_owner}); - assert.isTrue(tx.logs[0].args._status); - }); + it("Should freeze the transfers", async () => { + let tx = await I_SecurityToken.freezeTransfers({ from: token_owner }); + assert.isTrue(tx.logs[0].args._status); + }); - it("Should fail to freeze the transfers", async() => { - - await catchRevert(I_SecurityToken.freezeTransfers({from: token_owner})); - }); - - it("Should fail in buying to tokens", async() => { - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_temp, - fromTime, - toTime, - expiryTime, - true, - { - from: account_delegate, - gas: 6000000 - }); + it("Should fail to freeze the transfers", async () => { + await catchRevert(I_SecurityToken.freezeTransfers({ from: token_owner })); + }); + + it("Should fail in buying to tokens", async () => { + let tx = await I_GeneralTransferManager.modifyWhitelist(account_temp, fromTime, toTime, expiryTime, true, { + from: account_delegate, + gas: 6000000 + }); assert.equal(tx.logs[0].args._investor, account_temp, "Failed in adding the investor in whitelist"); - - await catchRevert(web3.eth.sendTransaction({ + await catchRevert( + web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, gas: 2100000, - value: web3.utils.toWei('1', 'ether') - })); - }); - - it("Should fail in trasfering the tokens from one user to another", async() => { - await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); - console.log(await I_SecurityToken.balanceOf(account_investor1)); - - await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp})); - }); - - it("Should unfreeze all the transfers", async() => { - let tx = await I_SecurityToken.unfreezeTransfers({from: token_owner}); - assert.isFalse(tx.logs[0].args._status); - }); - - it("Should freeze the transfers", async() => { - - await catchRevert(I_SecurityToken.unfreezeTransfers({from: token_owner})); - }); + value: web3.utils.toWei("1", "ether") + }) + ); + }); - it("Should able to transfers the tokens from one user to another", async() => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_temp}); - }); - - it("Should check that the list of investors is correct", async ()=> { - // Hardcode list of expected accounts based on transfers above - - let investors = await I_SecurityToken.getInvestors(); - let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1, account_temp]; - for (let i = 0; i < expectedAccounts.length; i++) { - assert.equal(investors[i], expectedAccounts[i]); - } - assert.equal(investors.length, 4); - console.log("Total Seen Investors: " + investors.length); - }); - it("Should fail to set controller status because msg.sender not owner", async() => { - - await catchRevert(I_SecurityToken.setController(account_controller, {from: account_controller})); - }); - - it("Should successfully set controller", async() => { - let tx1 = await I_SecurityToken.setController(account_controller, {from: token_owner}); - - // check event - assert.equal(address_zero, tx1.logs[0].args._oldController, "Event not emitted as expected"); - assert.equal(account_controller, tx1.logs[0].args._newController, "Event not emitted as expected"); - - let tx2 = await I_SecurityToken.setController(address_zero, {from: token_owner}); - - // check event - assert.equal(account_controller, tx2.logs[0].args._oldController, "Event not emitted as expected"); - assert.equal(address_zero, tx2.logs[0].args._newController, "Event not emitted as expected"); - - let tx3 = await I_SecurityToken.setController(account_controller, {from: token_owner}); - - // check event - assert.equal(address_zero, tx3.logs[0].args._oldController, "Event not emitted as expected"); - assert.equal(account_controller, tx3.logs[0].args._newController, "Event not emitted as expected"); - - // check status - let controller = await I_SecurityToken.controller.call(); - assert.equal(account_controller, controller, "Status not set correctly"); - }); - - it("Should force burn the tokens - value too high", async ()=> { - - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", "", { from: account_controller })); - }); - it("Should force burn the tokens - wrong caller", async ()=> { - - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); - let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance, "", "", { from: token_owner })); - }); - - it("Should burn the tokens", async ()=> { - let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); - let currentBalance = await I_SecurityToken.balanceOf(account_temp); - // console.log(currentInvestorCount.toString(), currentBalance.toString()); - let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", "", { from: account_controller }); - // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); - assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); - let newInvestorCount = await I_SecurityToken.getInvestorCount.call(); - // console.log(newInvestorCount.toString()); - assert.equal(newInvestorCount.toNumber() + 1, currentInvestorCount.toNumber(), "Investor count drops by one"); - }); - - it("Should prune investor length", async ()=> { - await I_SecurityToken.pruneInvestors(0, 10, {from: token_owner}); - // Hardcode list of expected accounts based on transfers above - - let investors = await I_SecurityToken.getInvestors.call(); - let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1]; - for (let i = 0; i < expectedAccounts.length; i++) { - assert.equal(investors[i], expectedAccounts[i]); - } - assert.equal(investors.length, 3); - }); - - it("Should check the balance of investor at checkpoint", async() => { - - await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); - }); - - it("Should check the balance of investor at checkpoint", async() => { - let balance = await I_SecurityToken.balanceOfAt(account_investor1, 0); - assert.equal(balance.toNumber(), 0); - }); + it("Should fail in trasfering the tokens from one user to another", async () => { + await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from: token_owner }); + console.log(await I_SecurityToken.balanceOf(account_investor1)); + + await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei("1", "ether"), { from: account_temp })); }); - describe("Withdraw Poly", async() => { + it("Should unfreeze all the transfers", async () => { + let tx = await I_SecurityToken.unfreezeTransfers({ from: token_owner }); + assert.isFalse(tx.logs[0].args._status); + }); - it("Should successfully withdraw the poly", async() => { - - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: account_temp})); - }) + it("Should freeze the transfers", async () => { + await catchRevert(I_SecurityToken.unfreezeTransfers({ from: token_owner })); + }); - it("Should successfully withdraw the poly", async() => { - let balanceBefore = await I_PolyToken.balanceOf(token_owner); - await I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), {from: token_owner}); - let balanceAfter = await I_PolyToken.balanceOf(token_owner); - assert.equal((BigNumber(balanceAfter).sub(BigNumber(balanceBefore))).toNumber(), web3.utils.toWei("20000", "ether")); - }); + it("Should able to transfers the tokens from one user to another", async () => { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei("1", "ether"), { from: account_temp }); + }); - it("Should successfully withdraw the poly", async() => { - - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), {from: token_owner})); - }); + it("Should check that the list of investors is correct", async () => { + // Hardcode list of expected accounts based on transfers above + + let investors = await I_SecurityToken.getInvestors(); + let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1, account_temp]; + for (let i = 0; i < expectedAccounts.length; i++) { + assert.equal(investors[i], expectedAccounts[i]); + } + assert.equal(investors.length, 4); + console.log("Total Seen Investors: " + investors.length); + }); + it("Should fail to set controller status because msg.sender not owner", async () => { + await catchRevert(I_SecurityToken.setController(account_controller, { from: account_controller })); }); - describe("Force Transfer", async() => { + it("Should successfully set controller", async () => { + let tx1 = await I_SecurityToken.setController(account_controller, { from: token_owner }); - it("Should fail to forceTransfer because not approved controller", async() => { - await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", {from: account_investor1})); - }); + // check event + assert.equal(address_zero, tx1.logs[0].args._oldController, "Event not emitted as expected"); + assert.equal(account_controller, tx1.logs[0].args._newController, "Event not emitted as expected"); - it("Should fail to forceTransfer because insufficient balance", async() => { - - await catchRevert(I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller})); - }); + let tx2 = await I_SecurityToken.setController(address_zero, { from: token_owner }); - it("Should fail to forceTransfer because recipient is zero address", async() => { - - await catchRevert(I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller})); - }); + // check event + assert.equal(account_controller, tx2.logs[0].args._oldController, "Event not emitted as expected"); + assert.equal(address_zero, tx2.logs[0].args._newController, "Event not emitted as expected"); - it("Should successfully forceTransfer", async() => { - let sender = account_investor1; - let receiver = account_investor2; - - let start_investorCount = await I_SecurityToken.getInvestorCount.call(); - let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); - let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); - - let tx = await I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller}); - - let end_investorCount = await I_SecurityToken.getInvestorCount.call(); - let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); - let end_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); - - assert.equal(start_investorCount.add(1).toNumber(), end_investorCount.toNumber(), "Investor count not changed"); - assert.equal(start_balInv1.sub(web3.utils.toWei("10", "ether")).toNumber(), end_balInv1.toNumber(), "Investor balance not changed"); - assert.equal(start_balInv2.add(web3.utils.toWei("10", "ether")).toNumber(), end_balInv2.toNumber(), "Investor balance not changed"); - console.log(tx.logs[0].args); - console.log(tx.logs[1].args); - assert.equal(account_controller, tx.logs[0].args._controller, "Event not emitted as expected"); - assert.equal(account_investor1, tx.logs[0].args._from, "Event not emitted as expected"); - assert.equal(account_investor2, tx.logs[0].args._to, "Event not emitted as expected"); - assert.equal(web3.utils.toWei("10", "ether"), tx.logs[0].args._value, "Event not emitted as expected"); - console.log(tx.logs[0].args._verifyTransfer); - assert.equal(false, tx.logs[0].args._verifyTransfer, "Event not emitted as expected"); - assert.equal("reason", web3.utils.hexToUtf8(tx.logs[0].args._data), "Event not emitted as expected"); - - assert.equal(account_investor1, tx.logs[1].args.from, "Event not emitted as expected"); - assert.equal(account_investor2, tx.logs[1].args.to, "Event not emitted as expected"); - assert.equal(web3.utils.toWei("10", "ether"), tx.logs[1].args.value, "Event not emitted as expected"); - }); + let tx3 = await I_SecurityToken.setController(account_controller, { from: token_owner }); - it("Should fail to freeze controller functionality because not owner", async() => { - - await catchRevert(I_SecurityToken.disableController({from: account_investor1})); - }); + // check event + assert.equal(address_zero, tx3.logs[0].args._oldController, "Event not emitted as expected"); + assert.equal(account_controller, tx3.logs[0].args._newController, "Event not emitted as expected"); - it("Should fail to freeze controller functionality because disableControllerAllowed not activated", async() => { - - await catchRevert(I_SecurityToken.disableController({from: token_owner})); - }); + // check status + let controller = await I_SecurityToken.controller.call(); + assert.equal(account_controller, controller, "Status not set correctly"); + }); + + it("Should force burn the tokens - value too high", async () => { + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); + let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + await catchRevert( + I_SecurityToken.forceBurn(account_temp, currentBalance + web3.utils.toWei("500", "ether"), "", "", { + from: account_controller + }) + ); + }); + it("Should force burn the tokens - wrong caller", async () => { + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); + let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + await catchRevert(I_SecurityToken.forceBurn(account_temp, currentBalance, "", "", { from: token_owner })); + }); - it("Should successfully freeze controller functionality", async() => { - let tx1 = await I_FeatureRegistry.setFeatureStatus("disableControllerAllowed", true, {from: account_polymath}); + it("Should burn the tokens", async () => { + let currentInvestorCount = await I_SecurityToken.getInvestorCount.call(); + let currentBalance = await I_SecurityToken.balanceOf(account_temp); + // console.log(currentInvestorCount.toString(), currentBalance.toString()); + let tx = await I_SecurityToken.forceBurn(account_temp, currentBalance, "", "", { from: account_controller }); + // console.log(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); + assert.equal(tx.logs[0].args._value.toNumber(), currentBalance.toNumber()); + let newInvestorCount = await I_SecurityToken.getInvestorCount.call(); + // console.log(newInvestorCount.toString()); + assert.equal(newInvestorCount.toNumber() + 1, currentInvestorCount.toNumber(), "Investor count drops by one"); + }); - // check event - assert.equal("disableControllerAllowed", tx1.logs[0].args._nameKey, "Event not emitted as expected"); - assert.equal(true, tx1.logs[0].args._newStatus, "Event not emitted as expected"); + it("Should prune investor length", async () => { + await I_SecurityToken.pruneInvestors(0, 10, { from: token_owner }); + // Hardcode list of expected accounts based on transfers above - let tx2 = await I_SecurityToken.disableController({from: token_owner}); + let investors = await I_SecurityToken.getInvestors.call(); + let expectedAccounts = [account_affiliate1, account_affiliate2, account_investor1]; + for (let i = 0; i < expectedAccounts.length; i++) { + assert.equal(investors[i], expectedAccounts[i]); + } + assert.equal(investors.length, 3); + }); - // check state - assert.equal(address_zero, await I_SecurityToken.controller.call(), "State not changed"); - assert.equal(true, await I_SecurityToken.controllerDisabled.call(), "State not changed"); - }); + it("Should check the balance of investor at checkpoint", async () => { + await catchRevert(I_SecurityToken.balanceOfAt(account_investor1, 5)); + }); - it("Should fail to freeze controller functionality because already frozen", async() => { - - await catchRevert(I_SecurityToken.disableController({from: token_owner})); - }); + it("Should check the balance of investor at checkpoint", async () => { + let balance = await I_SecurityToken.balanceOfAt(account_investor1, 0); + assert.equal(balance.toNumber(), 0); + }); + }); - it("Should fail to set controller because controller functionality frozen", async() => { - - await catchRevert(I_SecurityToken.setController(account_controller, {from: token_owner})); - }); + describe("Withdraw Poly", async () => { + it("Should successfully withdraw the poly", async () => { + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), { from: account_temp })); + }); - it("Should fail to forceTransfer because controller functionality frozen", async() => { - - await catchRevert(I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", {from: account_controller})); - }); + it("Should successfully withdraw the poly", async () => { + let balanceBefore = await I_PolyToken.balanceOf(token_owner); + await I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), { from: token_owner }); + let balanceAfter = await I_PolyToken.balanceOf(token_owner); + assert.equal( + BigNumber(balanceAfter) + .sub(BigNumber(balanceBefore)) + .toNumber(), + web3.utils.toWei("20000", "ether") + ); + }); + + it("Should successfully withdraw the poly", async () => { + await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), { from: token_owner })); + }); + }); + + describe("Force Transfer", async () => { + it("Should fail to forceTransfer because not approved controller", async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", { + from: account_investor1 + }) + ); + }); + + it("Should fail to forceTransfer because insufficient balance", async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor2, account_investor1, web3.utils.toWei("10", "ether"), "", "reason", { + from: account_controller + }) + ); + }); + it("Should fail to forceTransfer because recipient is zero address", async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor1, address_zero, web3.utils.toWei("10", "ether"), "", "reason", { + from: account_controller + }) + ); }); - }); + it("Should successfully forceTransfer", async () => { + let sender = account_investor1; + let receiver = account_investor2; + + let start_investorCount = await I_SecurityToken.getInvestorCount.call(); + let start_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); + let start_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); + + let tx = await I_SecurityToken.forceTransfer( + account_investor1, + account_investor2, + web3.utils.toWei("10", "ether"), + "", + "reason", + { from: account_controller } + ); + + let end_investorCount = await I_SecurityToken.getInvestorCount.call(); + let end_balInv1 = await I_SecurityToken.balanceOf.call(account_investor1); + let end_balInv2 = await I_SecurityToken.balanceOf.call(account_investor2); + + assert.equal(start_investorCount.add(1).toNumber(), end_investorCount.toNumber(), "Investor count not changed"); + assert.equal( + start_balInv1.sub(web3.utils.toWei("10", "ether")).toNumber(), + end_balInv1.toNumber(), + "Investor balance not changed" + ); + assert.equal( + start_balInv2.add(web3.utils.toWei("10", "ether")).toNumber(), + end_balInv2.toNumber(), + "Investor balance not changed" + ); + console.log(tx.logs[0].args); + console.log(tx.logs[1].args); + assert.equal(account_controller, tx.logs[0].args._controller, "Event not emitted as expected"); + assert.equal(account_investor1, tx.logs[0].args._from, "Event not emitted as expected"); + assert.equal(account_investor2, tx.logs[0].args._to, "Event not emitted as expected"); + assert.equal(web3.utils.toWei("10", "ether"), tx.logs[0].args._value, "Event not emitted as expected"); + console.log(tx.logs[0].args._verifyTransfer); + assert.equal(false, tx.logs[0].args._verifyTransfer, "Event not emitted as expected"); + assert.equal("reason", web3.utils.hexToUtf8(tx.logs[0].args._data), "Event not emitted as expected"); + + assert.equal(account_investor1, tx.logs[1].args.from, "Event not emitted as expected"); + assert.equal(account_investor2, tx.logs[1].args.to, "Event not emitted as expected"); + assert.equal(web3.utils.toWei("10", "ether"), tx.logs[1].args.value, "Event not emitted as expected"); + }); + + it("Should fail to freeze controller functionality because not owner", async () => { + await catchRevert(I_SecurityToken.disableController({ from: account_investor1 })); + }); + + it("Should fail to freeze controller functionality because disableControllerAllowed not activated", async () => { + await catchRevert(I_SecurityToken.disableController({ from: token_owner })); + }); + + it("Should successfully freeze controller functionality", async () => { + let tx1 = await I_FeatureRegistry.setFeatureStatus("disableControllerAllowed", true, { from: account_polymath }); + + // check event + assert.equal("disableControllerAllowed", tx1.logs[0].args._nameKey, "Event not emitted as expected"); + assert.equal(true, tx1.logs[0].args._newStatus, "Event not emitted as expected"); + + let tx2 = await I_SecurityToken.disableController({ from: token_owner }); + + // check state + assert.equal(address_zero, await I_SecurityToken.controller.call(), "State not changed"); + assert.equal(true, await I_SecurityToken.controllerDisabled.call(), "State not changed"); + }); + + it("Should fail to freeze controller functionality because already frozen", async () => { + await catchRevert(I_SecurityToken.disableController({ from: token_owner })); + }); + + it("Should fail to set controller because controller functionality frozen", async () => { + await catchRevert(I_SecurityToken.setController(account_controller, { from: token_owner })); + }); + + it("Should fail to forceTransfer because controller functionality frozen", async () => { + await catchRevert( + I_SecurityToken.forceTransfer(account_investor1, account_investor2, web3.utils.toWei("10", "ether"), "", "reason", { + from: account_controller + }) + ); + }); + }); +}); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 0f463d1a0..cd4d97df4 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -1,32 +1,32 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); -const USDTieredSTOProxyFactory = artifacts.require('./USDTieredSTOProxyFactory'); -const USDTieredSTO = artifacts.require('./USDTieredSTO.sol'); -const MockOracle = artifacts.require('./MockOracle.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); +const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory"); +const USDTieredSTO = artifacts.require("./USDTieredSTO.sol"); +const MockOracle = artifacts.require("./MockOracle.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port -contract('USDTieredSTO', accounts => { +contract("USDTieredSTO", accounts => { // Accounts Variable declaration let POLYMATH; let ISSUER; @@ -85,11 +85,11 @@ contract('USDTieredSTO', accounts => { const STOSetupCost = 0; // MockOracle USD prices - const USDETH = BigNumber(500).mul(10**18); // 500 USD/ETH - const USDPOLY = BigNumber(25).mul(10**16); // 0.25 USD/POLY + const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH + const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; // STO Configuration Arrays let _startTime = []; @@ -120,57 +120,70 @@ contract('USDTieredSTO', accounts => { address _usdToken ) */ const functionSignature = { - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_startTime' - },{ - type: 'uint256', - name: '_endTime' - },{ - type: 'uint256[]', - name: '_ratePerTier' - },{ - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - },{ - type: 'uint256[]', - name: '_tokensPerTier' - },{ - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - },{ - type: 'uint256', - name: '_nonAccreditedLimitUSD' - },{ - type: 'uint256', - name: '_minimumInvestmentUSD' - },{ - type: 'uint8[]', - name: '_fundRaiseTypes' - },{ - type: 'address', - name: '_wallet' - },{ - type: 'address', - name: '_reserveWallet' - },{ - type: 'address', - name: '_usdToken' - }] + name: "configure", + type: "function", + inputs: [ + { + type: "uint256", + name: "_startTime" + }, + { + type: "uint256", + name: "_endTime" + }, + { + type: "uint256[]", + name: "_ratePerTier" + }, + { + type: "uint256[]", + name: "_ratePerTierDiscountPoly" + }, + { + type: "uint256[]", + name: "_tokensPerTier" + }, + { + type: "uint256[]", + name: "_tokensPerTierDiscountPoly" + }, + { + type: "uint256", + name: "_nonAccreditedLimitUSD" + }, + { + type: "uint256", + name: "_minimumInvestmentUSD" + }, + { + type: "uint8[]", + name: "_fundRaiseTypes" + }, + { + type: "address", + name: "_wallet" + }, + { + type: "address", + name: "_reserveWallet" + }, + { + type: "address", + name: "_usdToken" + } + ] }; async function convert(_stoID, _tier, _discount, _currencyFrom, _currencyTo, _amount) { let USDTOKEN; - if (_discount) - USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTierDiscountPoly.call(_tier); - else - USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTier.call(_tier); + if (_discount) USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTierDiscountPoly.call(_tier); + else USDTOKEN = await I_USDTieredSTO_Array[_stoID].ratePerTier.call(_tier); if (_currencyFrom == "TOKEN") { - let tokenToUSD = _amount.div(10**18).mul(USDTOKEN.div(10**18)).mul(10**18); // TOKEN * USD/TOKEN = USD - if (_currencyTo == "USD") - return tokenToUSD; + let tokenToUSD = _amount + .div(10 ** 18) + .mul(USDTOKEN.div(10 ** 18)) + .mul(10 ** 18); // TOKEN * USD/TOKEN = USD + if (_currencyTo == "USD") return tokenToUSD; if (_currencyTo == "ETH") { return await I_USDTieredSTO_Array[_stoID].convertFromUSD(ETH, tokenToUSD); } else if (_currencyTo == "POLY") { @@ -178,22 +191,19 @@ contract('USDTieredSTO', accounts => { } } if (_currencyFrom == "USD") { - if (_currencyTo == "TOKEN") - return _amount.div(USDTOKEN).mul(10**18); // USD / USD/TOKEN = TOKEN + if (_currencyTo == "TOKEN") return _amount.div(USDTOKEN).mul(10 ** 18); // USD / USD/TOKEN = TOKEN if (_currencyTo == "ETH" || _currencyTo == "POLY") - return await I_USDTieredSTO_Array[_stoID].convertFromUSD((_currencyTo == "ETH" ? ETH : POLY), _amount); + return await I_USDTieredSTO_Array[_stoID].convertFromUSD(_currencyTo == "ETH" ? ETH : POLY, _amount); } if (_currencyFrom == "ETH" || _currencyFrom == "POLY") { - let ethToUSD = await I_USDTieredSTO_Array[_stoID].convertToUSD((_currencyTo == "ETH" ? ETH : POLY), _amount); - if (_currencyTo == "USD") - return ethToUSD; - if (_currencyTo == "TOKEN") - return ethToUSD.div(USDTOKEN).mul(10**18); // USD / USD/TOKEN = TOKEN + let ethToUSD = await I_USDTieredSTO_Array[_stoID].convertToUSD(_currencyTo == "ETH" ? ETH : POLY, _amount); + if (_currencyTo == "USD") return ethToUSD; + if (_currencyTo == "TOKEN") return ethToUSD.div(USDTOKEN).mul(10 ** 18); // USD / USD/TOKEN = TOKEN } return 0; } - before(async() => { + before(async () => { // Accounts setup POLYMATH = accounts[0]; ISSUER = accounts[1]; @@ -210,28 +220,26 @@ contract('USDTieredSTO', accounts => { // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); + I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), ISSUER); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: POLYMATH - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: POLYMATH + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); + I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 3: Deploy the GeneralTransferManagerFactory @@ -259,7 +267,9 @@ contract('USDTieredSTO', accounts => { // STEP 6: Deploy the USDTieredSTOFactory - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: ISSUER }); + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { + from: ISSUER + }); assert.notEqual( I_USDTieredSTOFactory.address.valueOf(), @@ -267,53 +277,55 @@ contract('USDTieredSTO', accounts => { "USDTieredSTOFactory contract was not deployed" ); - // Step 8: Deploy the STFactory contract + // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - // Step 9: Deploy the SecurityTokenRegistry contract + // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + REGFEE, + REGFEE, + I_PolyToken.address, + POLYMATH + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: POLYMATH}); - await I_MRProxied.updateFromRegistry({from: POLYMATH}); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); + await I_MRProxied.updateFromRegistry({ from: POLYMATH }); + // STEP 7: Register the Modules with the ModuleRegistry contract - // STEP 7: Register the Modules with the ModuleRegistry contract + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); + await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); // Step 12: Deploy & Register Mock Oracles I_USDOracle = await MockOracle.new(0, "ETH", "USD", USDETH, { from: POLYMATH }); // 500 dollars per POLY @@ -342,12 +354,11 @@ contract('USDTieredSTO', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.getTokens(REGFEE, ISSUER); await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from : ISSUER }); + let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from: ISSUER }); assert.equal(tx.logs[0].args._owner, ISSUER); assert.equal(tx.logs[0].args._ticker, SYMBOL); }); @@ -361,65 +372,104 @@ contract('USDTieredSTO', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), TMKEY); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(TMKEY))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(TMKEY))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); }); - describe("Test sto deployment", async() => { - + describe("Test sto deployment", async () => { it("Should successfully attach the first STO module to the security token", async () => { let stoId = 0; // No discount _startTime.push(latestTime() + duration.days(2)); _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] - _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(15*10**16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] - _tokensPerTierTotal.push([BigNumber(100000000).mul(BigNumber(10**18)), BigNumber(200000000).mul(BigNumber(10**18))]); // [ 100m Token, 200m Token ] - _tokensPerTierDiscountPoly.push([BigNumber(0),BigNumber(0)]); // [ 0, 0 ] - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); // 10k USD - _minimumInvestmentUSD.push(BigNumber(5*10**18)); // 5 USD + _ratePerTier.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); // [ 0.10 USD/Token, 0.15 USD/Token ] + _tokensPerTierTotal.push([BigNumber(100000000).mul(BigNumber(10 ** 18)), BigNumber(200000000).mul(BigNumber(10 ** 18))]); // [ 100m Token, 200m Token ] + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0)]); // [ 0, 0 ] + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); // 10k USD + _minimumInvestmentUSD.push(BigNumber(5 * 10 ** 18)); // 5 USD _fundRaiseTypes.push([0, 1, 2]); _wallet.push(WALLET); _reserveWallet.push(RESERVEWALLET); _usdToken.push(I_DaiToken.address); let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], "Incorrect _startTime in config"); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], "Incorrect _endTime in config"); for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), + _ratePerTier[stoId][i].toNumber(), + "Incorrect _ratePerTier in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), + _ratePerTierDiscountPoly[stoId][i].toNumber(), + "Incorrect _ratePerTierDiscountPoly in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), + _tokensPerTierTotal[stoId][i].toNumber(), + "Incorrect _tokensPerTierTotal in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), + _tokensPerTierDiscountPoly[stoId][i].toNumber(), + "Incorrect _tokensPerTierDiscountPoly in config" + ); } - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].usdToken.call()), _usdToken[stoId], "Incorrect _usdToken in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].getNumberOfTiers()), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + _nonAccreditedLimitUSD[stoId].toNumber(), + "Incorrect _nonAccreditedLimitUSD in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + _minimumInvestmentUSD[stoId].toNumber(), + "Incorrect _minimumInvestmentUSD in config" + ); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], "Incorrect _wallet in config"); + assert.equal( + await I_USDTieredSTO_Array[stoId].reserveWallet.call(), + _reserveWallet[stoId], + "Incorrect _reserveWallet in config" + ); + assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(), _usdToken[stoId], "Incorrect _usdToken in config"); + assert.equal( + await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), + _tokensPerTierTotal[stoId].length, + "Incorrect number of tiers" + ); assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); }); @@ -428,11 +478,32 @@ contract('USDTieredSTO', accounts => { _startTime.push(latestTime() + duration.days(2)); _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16)]); - _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16), BigNumber(15*10**16)]); - _tokensPerTierTotal.push([BigNumber(5*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(10*10**18), BigNumber(50*10**18)]); + _ratePerTier.push([ + BigNumber(10 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16) + ]); + _ratePerTierDiscountPoly.push([ + BigNumber(10 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16), + BigNumber(15 * 10 ** 16) + ]); + _tokensPerTierTotal.push([ + BigNumber(5 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(10 * 10 ** 18), + BigNumber(50 * 10 ** 18) + ]); _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0), BigNumber(0)]); - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); _minimumInvestmentUSD.push(BigNumber(0)); _fundRaiseTypes.push([0, 1, 2]); _wallet.push(WALLET); @@ -440,32 +511,73 @@ contract('USDTieredSTO', accounts => { _usdToken.push(I_DaiToken.address); let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], "Incorrect _startTime in config"); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], "Incorrect _endTime in config"); for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), + _ratePerTier[stoId][i].toNumber(), + "Incorrect _ratePerTier in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), + _ratePerTierDiscountPoly[stoId][i].toNumber(), + "Incorrect _ratePerTierDiscountPoly in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), + _tokensPerTierTotal[stoId][i].toNumber(), + "Incorrect _tokensPerTierTotal in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), + _tokensPerTierDiscountPoly[stoId][i].toNumber(), + "Incorrect _tokensPerTierDiscountPoly in config" + ); } - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].usdToken.call()), _usdToken[stoId], "Incorrect _usdToken in config"); - assert.equal(await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + _nonAccreditedLimitUSD[stoId].toNumber(), + "Incorrect _nonAccreditedLimitUSD in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + _minimumInvestmentUSD[stoId].toNumber(), + "Incorrect _minimumInvestmentUSD in config" + ); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], "Incorrect _wallet in config"); + assert.equal( + await I_USDTieredSTO_Array[stoId].reserveWallet.call(), + _reserveWallet[stoId], + "Incorrect _reserveWallet in config" + ); + assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(), _usdToken[stoId], "Incorrect _usdToken in config"); + assert.equal( + await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), + _tokensPerTierTotal[stoId].length, + "Incorrect number of tiers" + ); assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); }); @@ -474,41 +586,50 @@ contract('USDTieredSTO', accounts => { _startTime.push(latestTime() + duration.days(2)); _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([BigNumber(1*10**18), BigNumber(1.5*10**18)]); // [ 1 USD/Token, 1.5 USD/Token ] - _ratePerTierDiscountPoly.push([BigNumber(0.5*10**18), BigNumber(1*10**18)]); // [ 0.5 USD/Token, 1.5 USD/Token ] - _tokensPerTierTotal.push([BigNumber(100*10**18), BigNumber(50*10**18)]); // [ 100 Token, 50 Token ] - _tokensPerTierDiscountPoly.push([BigNumber(100*10**18),BigNumber(25*10**18)]); // [ 100 Token, 25 Token ] - _nonAccreditedLimitUSD.push(BigNumber(25*10**18)); // [ 25 USD ] + _ratePerTier.push([BigNumber(1 * 10 ** 18), BigNumber(1.5 * 10 ** 18)]); // [ 1 USD/Token, 1.5 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(0.5 * 10 ** 18), BigNumber(1 * 10 ** 18)]); // [ 0.5 USD/Token, 1.5 USD/Token ] + _tokensPerTierTotal.push([BigNumber(100 * 10 ** 18), BigNumber(50 * 10 ** 18)]); // [ 100 Token, 50 Token ] + _tokensPerTierDiscountPoly.push([BigNumber(100 * 10 ** 18), BigNumber(25 * 10 ** 18)]); // [ 100 Token, 25 Token ] + _nonAccreditedLimitUSD.push(BigNumber(25 * 10 ** 18)); // [ 25 USD ] _minimumInvestmentUSD.push(BigNumber(5)); _fundRaiseTypes.push([0, 1, 2]); _wallet.push(WALLET); _reserveWallet.push(RESERVEWALLET); - _usdToken.push(I_DaiToken.address) + _usdToken.push(I_DaiToken.address); let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); }); it("Should successfully attach the fourth STO module to the security token", async () => { let stoId = 3; - _startTime.push(latestTime()+ duration.days(0.1)); + _startTime.push(latestTime() + duration.days(0.1)); _endTime.push(_startTime[stoId] + duration.days(0.1)); - _ratePerTier.push([BigNumber(10*10**16), BigNumber(15*10**16)]); - _ratePerTierDiscountPoly.push([BigNumber(10*10**16), BigNumber(12*10**16)]); - _tokensPerTierTotal.push([BigNumber(100*10**18), BigNumber(200*10**18)]); - _tokensPerTierDiscountPoly.push([BigNumber(0),BigNumber(50*10**18)]); - _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10**18))); + _ratePerTier.push([BigNumber(10 * 10 ** 16), BigNumber(15 * 10 ** 16)]); + _ratePerTierDiscountPoly.push([BigNumber(10 * 10 ** 16), BigNumber(12 * 10 ** 16)]); + _tokensPerTierTotal.push([BigNumber(100 * 10 ** 18), BigNumber(200 * 10 ** 18)]); + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(50 * 10 ** 18)]); + _nonAccreditedLimitUSD.push(BigNumber(10000).mul(BigNumber(10 ** 18))); _minimumInvestmentUSD.push(BigNumber(0)); _fundRaiseTypes.push([0, 1, 2]); _wallet.push(WALLET); @@ -516,20 +637,29 @@ contract('USDTieredSTO', accounts => { _usdToken.push(I_DaiToken.address); let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); }); - it("Should fail because rates and tier array of different length", async() => { + it("Should fail because rates and tier array of different length", async () => { let stoId = 0; let ratePerTier = [10]; @@ -537,151 +667,322 @@ contract('USDTieredSTO', accounts => { let tokensPerTierTotal = [10]; let tokensPerTierDiscountPoly = [10]; let config = [ - [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], - [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], ratePerTierDiscountPoly, _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], - [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], tokensPerTierTotal, _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]], - [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], tokensPerTierDiscountPoly, _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]] + [ + _startTime[stoId], + _endTime[stoId], + ratePerTier, + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ], + [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + ratePerTierDiscountPoly, + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ], + [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + tokensPerTierTotal, + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ], + [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + tokensPerTierDiscountPoly, + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ] ]; for (var i = 0; i < config.length; i++) { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); - + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); } }); - it("Should fail because rate of token should be greater than 0", async() => { + it("Should fail because rate of token should be greater than 0", async () => { let stoId = 0; - let ratePerTier = [BigNumber(10*10**16), BigNumber(0)]; - let config = [_startTime[stoId], _endTime[stoId], ratePerTier, _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let ratePerTier = [BigNumber(10 * 10 ** 16), BigNumber(0)]; + let config = [ + _startTime[stoId], + _endTime[stoId], + ratePerTier, + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); - it("Should fail because Zero address is not permitted for wallet", async() => { + it("Should fail because Zero address is not permitted for wallet", async () => { let stoId = 0; let wallet = "0x0000000000000000000000000000000000000000"; - let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], wallet, _reserveWallet[stoId], _usdToken[stoId]]; + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + wallet, + _reserveWallet[stoId], + _usdToken[stoId] + ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); - it("Should fail because Zero address is not permitted for reserveWallet", async() => { + it("Should fail because Zero address is not permitted for reserveWallet", async () => { let stoId = 0; let reserveWallet = "0x0000000000000000000000000000000000000000"; - let config = [_startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], reserveWallet]; + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + reserveWallet + ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); - it("Should fail because end time before start time", async() => { + it("Should fail because end time before start time", async () => { let stoId = 0; let startTime = latestTime() + duration.days(35); - let endTime = latestTime() + duration.days(1); - let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let endTime = latestTime() + duration.days(1); + let config = [ + startTime, + endTime, + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); - it("Should fail because start time is in the past", async() => { + it("Should fail because start time is in the past", async () => { let stoId = 0; let startTime = latestTime() - duration.days(35); - let endTime = startTime + duration.days(50); - let config = [startTime, endTime, _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId]]; + let endTime = startTime + duration.days(50); + let config = [ + startTime, + endTime, + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER })); }); }); - describe("Test modifying configuration", async() => { - - it("Should successfully change config before startTime - funding", async() => { + describe("Test modifying configuration", async () => { + it("Should successfully change config before startTime - funding", async () => { let stoId = 3; await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),false,"STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), true, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), false, "STO Configuration doesn't set as expected"); await I_USDTieredSTO_Array[stoId].modifyFunding([1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),false,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0),true,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1),true,"STO Configuration doesn't set as expected"); - + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), false, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), true, "STO Configuration doesn't set as expected"); + await I_USDTieredSTO_Array[stoId].modifyFunding([0, 1], { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(0), true, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].fundRaiseTypes.call(1), true, "STO Configuration doesn't set as expected"); }); - it("Should successfully change config before startTime - limits and tiers, times, addresses", async() => { + it("Should successfully change config before startTime - limits and tiers, times, addresses", async () => { let stoId = 3; - await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1*10**18), BigNumber(15*10**18), { from: ISSUER }); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(),BigNumber(1*10**18).toNumber(),"STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER }); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(),BigNumber(15*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(),BigNumber(13*10**18).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0)),BigNumber(15*10**20).toNumber(),"STO Configuration doesn't set as expected"); + await I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(1 * 10 ** 18), BigNumber(15 * 10 ** 18), { from: ISSUER }); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + BigNumber(15 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + BigNumber(1 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + + await I_USDTieredSTO_Array[stoId].modifyTiers( + [BigNumber(15 * 10 ** 18)], + [BigNumber(13 * 10 ** 18)], + [BigNumber(15 * 10 ** 20)], + [BigNumber(15 * 10 ** 20)], + { from: ISSUER } + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(0)).toNumber(), + BigNumber(15 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(0)).toNumber(), + BigNumber(13 * 10 ** 18).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(0), + BigNumber(15 * 10 ** 20).toNumber(), + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(0), + BigNumber(15 * 10 ** 20).toNumber(), + "STO Configuration doesn't set as expected" + ); let tempTime1 = latestTime() + duration.days(0.1); let tempTime2 = latestTime() + duration.days(0.2); await I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(),tempTime1,"STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(),tempTime2,"STO Configuration doesn't set as expected"); - - await I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", "0x0000000000000000000000000000000000000000", { from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(),"0x0000000000000000000000000400000000000000","STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].reserveWallet.call(),"0x0000000000000000000003000000000000000000","STO Configuration doesn't set as expected"); - assert.equal(await I_USDTieredSTO_Array[stoId].usdToken.call(),"0x0000000000000000000000000000000000000000","STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), tempTime1, "STO Configuration doesn't set as expected"); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), tempTime2, "STO Configuration doesn't set as expected"); + + await I_USDTieredSTO_Array[stoId].modifyAddresses( + "0x0000000000000000000000000400000000000000", + "0x0000000000000000000003000000000000000000", + "0x0000000000000000000000000000000000000000", + { from: ISSUER } + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].wallet.call(), + "0x0000000000000000000000000400000000000000", + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].reserveWallet.call(), + "0x0000000000000000000003000000000000000000", + "STO Configuration doesn't set as expected" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].usdToken.call(), + "0x0000000000000000000000000000000000000000", + "STO Configuration doesn't set as expected" + ); }); - it("Should fail to change config after endTime", async() => { + it("Should fail to change config after endTime", async () => { let stoId = 3; let snapId = await takeSnapshot(); await increaseTime(duration.days(1)); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0,1], { from: ISSUER })); + await catchRevert(I_USDTieredSTO_Array[stoId].modifyFunding([0, 1], { from: ISSUER })); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15*10**18), BigNumber(1*10**18), { from: ISSUER })); + await catchRevert( + I_USDTieredSTO_Array[stoId].modifyLimits(BigNumber(15 * 10 ** 18), BigNumber(1 * 10 ** 18), { from: ISSUER }) + ); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyTiers([BigNumber(15*10**18)], [BigNumber(13*10**18)], [BigNumber(15*10**20)], [BigNumber(15*10**20)], { from: ISSUER })); + await catchRevert( + I_USDTieredSTO_Array[stoId].modifyTiers( + [BigNumber(15 * 10 ** 18)], + [BigNumber(13 * 10 ** 18)], + [BigNumber(15 * 10 ** 20)], + [BigNumber(15 * 10 ** 20)], + { from: ISSUER } + ) + ); let tempTime1 = latestTime(); let tempTime2 = latestTime() + duration.days(3); - await catchRevert(I_USDTieredSTO_Array[stoId].modifyTimes(tempTime1, tempTime2, { from: ISSUER })); - - await catchRevert(I_USDTieredSTO_Array[stoId].modifyAddresses("0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", I_DaiToken.address, { from: ISSUER })); + await catchRevert( + I_USDTieredSTO_Array[stoId].modifyAddresses( + "0x0000000000000000000000000400000000000000", + "0x0000000000000000000003000000000000000000", + I_DaiToken.address, + { from: ISSUER } + ) + ); await revertToSnapshot(snapId); }); }); - describe("Test buying failure conditions", async() => { - - it("should fail if before STO start time", async() => { + describe("Test buying failure conditions", async () => { + it("should fail if before STO start time", async () => { let stoId = 0; let snapId = await takeSnapshot(); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, "STO is not showing correct status"); // Whitelist let fromTime = latestTime(); @@ -689,8 +990,8 @@ contract('USDTieredSTO', accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); // // Advance time to after STO start // await increaseTime(duration.days(3)); @@ -699,88 +1000,110 @@ contract('USDTieredSTO', accounts => { await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + let investment_ETH = web3.utils.toWei("1", "ether"); // Invest 1 ETH + let investment_POLY = web3.utils.toWei("10000", "ether"); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + let investment_DAI = web3.utils.toWei("500", "ether"); // Invest 10000 POLY await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // NONACCREDITED ETH - + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); }); - it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { + it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async () => { let stoId = 0; let tierId; // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - let investment_USD = BigNumber(web3.utils.toWei('50')); // USD - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_USD = BigNumber(web3.utils.toWei("50")); // USD + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); // Change exchange rates up await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_high, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_low, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); }); - it("should successfully buy across tiers for NONACCREDITED ETH", async() => { + it("should successfully buy across tiers for NONACCREDITED ETH", async () => { let stoId = 1; let startTier = 0; let endTier = 1; - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), + startTier, + "currentTier not changed as expected" + ); - let delta_Token = BigNumber(5).mul(10**18); + let delta_Token = BigNumber(5).mul(10 ** 18); let ethTier0 = await convert(stoId, startTier, false, "TOKEN", "ETH", delta_Token); let ethTier1 = await convert(stoId, endTier, false, "TOKEN", "ETH", delta_Token); let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH + let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH // Process investment let init_TokenSupply = await I_SecurityToken.totalSupply(); @@ -795,9 +1118,13 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithETH: ".grey + tx1.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -811,38 +1138,69 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); // Additional Checks assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); }); - it("should successfully buy across tiers for NONACCREDITED POLY", async() => { + it("should successfully buy across tiers for NONACCREDITED POLY", async () => { let stoId = 1; let startTier = 1; let endTier = 2; - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), + startTier, + "currentTier not changed as expected" + ); - let delta_Token = BigNumber(5).mul(10**18); // Token + let delta_Token = BigNumber(5).mul(10 ** 18); // Token let polyTier0 = await convert(stoId, startTier, false, "TOKEN", "POLY", delta_Token); let polyTier1 = await convert(stoId, endTier, false, "TOKEN", "POLY", delta_Token); - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); // Process investment let init_TokenSupply = await I_SecurityToken.totalSupply(); @@ -857,9 +1215,12 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -873,37 +1234,69 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); // Additional Checks assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); }); - it("should successfully buy across tiers for ACCREDITED ETH", async() => { + it("should successfully buy across tiers for ACCREDITED ETH", async () => { let stoId = 1; let startTier = 2; let endTier = 3; await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), + startTier, + "currentTier not changed as expected" + ); - let delta_Token = BigNumber(5).mul(10**18); // Token + let delta_Token = BigNumber(5).mul(10 ** 18); // Token let ethTier0 = await convert(stoId, startTier, false, "TOKEN", "ETH", delta_Token); let ethTier1 = await convert(stoId, endTier, false, "TOKEN", "ETH", delta_Token); let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH + let investment_ETH = ethTier0.add(ethTier1); // 0.0025 ETH // Process investment let init_TokenSupply = await I_SecurityToken.totalSupply(); @@ -918,9 +1311,13 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { + from: ACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithETH: ".grey + tx1.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -934,39 +1331,69 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); // Additional Checks assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); }); - it("should successfully buy across tiers for ACCREDITED DAI", async() => { - + it("should successfully buy across tiers for ACCREDITED DAI", async () => { let stoId = 1; let startTier = 3; let endTier = 4; - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), + startTier, + "currentTier not changed as expected" + ); - let delta_Token = BigNumber(5).mul(10**18); // Token + let delta_Token = BigNumber(5).mul(10 ** 18); // Token let daiTier0 = await convert(stoId, startTier, false, "TOKEN", "USD", delta_Token); let daiTier1 = await convert(stoId, endTier, false, "TOKEN", "USD", delta_Token); - let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_Token = delta_Token.add(delta_Token); // 10 Token let investment_DAI = daiTier0.add(daiTier1); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // Process investment let init_TokenSupply = await I_SecurityToken.totalSupply(); @@ -986,7 +1413,7 @@ contract('USDTieredSTO', accounts => { let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithUSD: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithUSD: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1003,12 +1430,36 @@ contract('USDTieredSTO', accounts => { let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_InvestorDAIBal.toNumber(), + init_InvestorDAIBal.sub(investment_DAI).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); @@ -1016,29 +1467,36 @@ contract('USDTieredSTO', accounts => { assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), "Raised DAI not changed as expected"); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - assert.equal(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletDAIBal.toNumber(), + init_WalletDAIBal.add(investment_DAI).toNumber(), + "Wallet POLY Balance not changed as expected" + ); // Additional Checks assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); - }); - it("should successfully buy across tiers for ACCREDITED POLY", async() => { + it("should successfully buy across tiers for ACCREDITED POLY", async () => { let stoId = 1; let startTier = 4; let endTier = 5; - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), + startTier, + "currentTier not changed as expected" + ); - let delta_Token = BigNumber(5).mul(10**18); // Token + let delta_Token = BigNumber(5).mul(10 ** 18); // Token let polyTier0 = await convert(stoId, startTier, false, "TOKEN", "POLY", delta_Token); let polyTier1 = await convert(stoId, endTier, false, "TOKEN", "POLY", delta_Token); - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); // Process investment let init_TokenSupply = await I_SecurityToken.totalSupply(); @@ -1053,9 +1511,12 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { + from: ACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1069,28 +1530,56 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); // Additional Checks assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); }); - it("should buy out the rest of the sto", async() => { + it("should buy out the rest of the sto", async () => { let stoId = 1; let tierId = 5; let minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(tierId); - console.log(minted.toNumber() + ":"+ _tokensPerTierTotal[stoId][tierId]); + console.log(minted.toNumber() + ":" + _tokensPerTierTotal[stoId][tierId]); let investment_Token = _tokensPerTierTotal[stoId][tierId].sub(minted); console.log(investment_Token.toNumber()); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); @@ -1099,24 +1588,40 @@ contract('USDTieredSTO', accounts => { let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - let tx = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); - console.log(" Gas buyWithETH: ".grey+tx.receipt.gasUsed.toString().grey); + let tx = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { + from: ACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); + console.log(" Gas buyWithETH: ".grey + tx.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); // assert.equal((await I_USDTieredSTO_Array[1].getTokensMinted()).toNumber(), _tokensPerTierTotal[1].reduce((a, b) => a + b, 0).toNumber(), "STO Token Sold not changed as expected"); }); - it("should fail and revert when all tiers sold out", async() => { + it("should fail and revert when all tiers sold out", async () => { let stoId = 1; let tierId = 4; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1128,93 +1633,129 @@ contract('USDTieredSTO', accounts => { await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, "STO is not showing correct status"); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with DAI NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with DAI ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); }); - it("should fail and revert when all tiers sold out despite oracle price change", async() => { + it("should fail and revert when all tiers sold out despite oracle price change", async () => { let stoId = 1; let tierId = 4; // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - let investment_USD = BigNumber(web3.utils.toWei('50')); // USD - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_USD = BigNumber(web3.utils.toWei("50")); // USD + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: ACCREDITED1 }); // Change exchange rates up await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_high, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_low, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); @@ -1222,13 +1763,12 @@ contract('USDTieredSTO', accounts => { }); }); - describe("Buy Tokens with POLY discount", async() => { - - it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async() => { + describe("Buy Tokens with POLY discount", async () => { + it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async () => { let stoId = 2; let tierId = 0; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1246,9 +1786,15 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await web3.eth.sendTransaction({ from: NONACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let tx1 = await web3.eth.sendTransaction({ + from: NONACCREDITED1, + to: I_USDTieredSTO_Array[stoId].address, + value: investment_ETH, + gasPrice: GAS_PRICE, + gas: 1000000 + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + console.log(" Gas fallback purchase: ".grey + tx1.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1263,35 +1809,90 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), "Raised USD not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); // Additional checks on getters assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), investment_Token.toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), investment_Token.toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), investment_Token.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), 0, "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), investment_USD.toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), investment_ETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), 0, "investorInvestedPOLY not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), + investment_Token.toNumber(), + "getTokensSold not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), + investment_Token.toNumber(), + "getTokensMinted not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), + investment_Token.toNumber(), + "getTokensSoldForETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), + 0, + "getTokensSoldForPOLY not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), + investment_USD.toNumber(), + "investorInvestedUSD not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), + investment_ETH.toNumber(), + "investorInvestedETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), + 0, + "investorInvestedPOLY not changed as expected" + ); }); - it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async() => { + it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async () => { let stoId = 2; let tierId = 0; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1308,9 +1909,13 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithETH: ".grey + tx1.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1324,30 +1929,57 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); }); - it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async() => { + it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async () => { let stoId = 2; let tierId = 0; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); let init_TokenSupply = await I_SecurityToken.totalSupply(); let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1362,9 +1994,12 @@ contract('USDTieredSTO', accounts => { let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1378,26 +2013,54 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); }); - it("should successfully buy using fallback at tier 0 for ACCREDITED1", async() => { + it("should successfully buy using fallback at tier 0 for ACCREDITED1", async () => { let stoId = 2; let tierId = 0; await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1414,9 +2077,15 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await web3.eth.sendTransaction({ from: ACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let tx1 = await web3.eth.sendTransaction({ + from: ACCREDITED1, + to: I_USDTieredSTO_Array[stoId].address, + value: investment_ETH, + gasPrice: GAS_PRICE, + gas: 1000000 + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + console.log(" Gas fallback purchase: ".grey + tx1.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1430,24 +2099,51 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); }); - it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async() => { + it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async () => { let stoId = 2; let tierId = 0; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1464,9 +2160,13 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { + from: ACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithETH: ".grey + tx1.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1480,30 +2180,57 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); }); - it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async() => { + it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async () => { let stoId = 2; let tierId = 0; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); // Additional checks on getters let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); @@ -1527,9 +2254,12 @@ contract('USDTieredSTO', accounts => { let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { + from: ACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1543,30 +2273,86 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); // Additional checks on getters assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), init_getTokensSold.add(investment_Token).toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), init_getTokensMinted.add(investment_Token).toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), init_getTokensSoldForETH.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), init_getTokensSoldForPOLY.add(investment_Token).toNumber(), "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), init_investorInvestedUSD.add(investment_USD).toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), init_investorInvestedETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), init_investorInvestedPOLY.add(investment_POLY).toNumber(), "investorInvestedPOLY not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), + init_getTokensSold.add(investment_Token).toNumber(), + "getTokensSold not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), + init_getTokensMinted.add(investment_Token).toNumber(), + "getTokensMinted not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), + init_getTokensSoldForETH.toNumber(), + "getTokensSoldForETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), + init_getTokensSoldForPOLY.add(investment_Token).toNumber(), + "getTokensSoldForPOLY not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), + init_investorInvestedUSD.add(investment_USD).toNumber(), + "investorInvestedUSD not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), + init_investorInvestedETH.toNumber(), + "investorInvestedETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), + init_investorInvestedPOLY.add(investment_POLY).toNumber(), + "investorInvestedPOLY not changed as expected" + ); }); - it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async() => { + it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async () => { let stoId = 2; let tierId = 0; @@ -1581,7 +2367,7 @@ contract('USDTieredSTO', accounts => { let refund_POLY = await convert(stoId, tierId, true, "USD", "POLY", refund_USD); await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); let init_TokenSupply = await I_SecurityToken.totalSupply(); let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1596,9 +2382,12 @@ contract('USDTieredSTO', accounts => { let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1612,118 +2401,190 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).add(refund_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal + .sub(investment_POLY) + .add(refund_POLY) + .toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).sub(refund_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).sub(refund_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + "Wallet POLY Balance not changed as expected" + ); }); - it("should fail and revert when NONACCREDITED cap reached", async() => { + it("should fail and revert when NONACCREDITED cap reached", async () => { let stoId = 2; let tierId = 0; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, true, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", investment_Token); await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1, gasPrice: GAS_PRICE}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); }); - it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async() => { + it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async () => { let stoId = 2; let tierId = 0; // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); // Change exchange rates up await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_high, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_low, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); }); - it("should successfully buy across tiers for POLY", async() => { + it("should successfully buy across tiers for POLY", async () => { let stoId = 2; let startTier = 0; let endTier = 1; - assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), startTier, "currentTier not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), + startTier, + "currentTier not changed as expected" + ); - let delta_Token = BigNumber(5).mul(10**18); // Token + let delta_Token = BigNumber(5).mul(10 ** 18); // Token let polyTier0 = await convert(stoId, startTier, true, "TOKEN", "POLY", delta_Token); let polyTier1 = await convert(stoId, endTier, true, "TOKEN", "POLY", delta_Token); - let investment_Token = delta_Token.add(delta_Token); // 10 Token - let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH + let investment_Token = delta_Token.add(delta_Token); // 10 Token + let investment_POLY = polyTier0.add(polyTier1); // 0.0025 ETH - let tokensRemaining = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier)); + let tokensRemaining = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)).sub( + await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier) + ); let prep_Token = tokensRemaining.sub(delta_Token); let prep_POLY = await convert(stoId, startTier, true, "TOKEN", "POLY", prep_Token); await I_PolyToken.getTokens(prep_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, prep_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, prep_POLY, { from: ACCREDITED1 }); let tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, prep_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); - console.log(" Gas buyWithPOLY: ".grey+tx.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx.receipt.gasUsed.toString().grey); - let Tier0Token = (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier)); - let Tier0Minted = (await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier)); + let Tier0Token = await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(startTier); + let Tier0Minted = await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(startTier); assert.equal(Tier0Minted.toNumber(), Tier0Token.sub(delta_Token).toNumber()); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); // Process investment let init_TokenSupply = await I_SecurityToken.totalSupply(); @@ -1738,9 +2599,12 @@ contract('USDTieredSTO', accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { + from: ACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1754,37 +2618,65 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); // Additional Checks assert.equal((await I_USDTieredSTO_Array[stoId].currentTier.call()).toNumber(), endTier, "currentTier not changed as expected"); }); - it("should successfully buy across the discount cap", async() => { + it("should successfully buy across the discount cap", async () => { let stoId = 2; let tierId = 1; - let discount_Token = BigNumber(20).mul(10**18); + let discount_Token = BigNumber(20).mul(10 ** 18); let discount_POLY = await convert(stoId, tierId, true, "TOKEN", "POLY", discount_Token); - let regular_Token = BigNumber(10).mul(10**18); + let regular_Token = BigNumber(10).mul(10 ** 18); let regular_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", regular_Token); let investment_Token = discount_Token.add(regular_Token); let investment_POLY = discount_POLY.add(regular_POLY); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); let init_TokenSupply = await I_SecurityToken.totalSupply(); let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1799,9 +2691,12 @@ contract('USDTieredSTO', accounts => { let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { + from: ACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1815,20 +2710,48 @@ contract('USDTieredSTO', accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); }); - it("should buy out the rest of the sto", async() => { + it("should buy out the rest of the sto", async () => { let stoId = 2; let tierId = 1; @@ -1837,31 +2760,46 @@ contract('USDTieredSTO', accounts => { let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); let init_TokenSupply = await I_SecurityToken.totalSupply(); let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { + from: ACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); }); - it("should fail and revert when all tiers sold out", async() => { + it("should fail and revert when all tiers sold out", async () => { let stoId = 2; let tierId = 1; - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1869,87 +2807,119 @@ contract('USDTieredSTO', accounts => { await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, "STO is not showing correct status"); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); }); - it("should fail and revert when all tiers sold out despite oracle price change", async() => { + it("should fail and revert when all tiers sold out despite oracle price change", async () => { let stoId = 2; let tierId = 1; // set new exchange rates - let high_USDETH = BigNumber(1000).mul(10**18); // 1000 USD per ETH - let high_USDPOLY = BigNumber(50).mul(10**16); // 0.5 USD per POLY - let low_USDETH = BigNumber(250).mul(10**18); // 250 USD per ETH - let low_USDPOLY = BigNumber(20).mul(10**16); // 0.2 USD per POLY + let high_USDETH = BigNumber(1000).mul(10 ** 18); // 1000 USD per ETH + let high_USDPOLY = BigNumber(50).mul(10 ** 16); // 0.5 USD per POLY + let low_USDETH = BigNumber(250).mul(10 ** 18); // 250 USD per ETH + let low_USDPOLY = BigNumber(20).mul(10 ** 16); // 0.2 USD per POLY - let investment_Token = BigNumber(5).mul(10**18); + let investment_Token = BigNumber(5).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, true, "TOKEN", "USD", investment_Token); - let investment_ETH_high = investment_USD.div(high_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10**18); // USD / USD/POLY = POLY - let investment_ETH_low = investment_USD.div(low_USDETH).mul(10**18); // USD / USD/ETH = ETH - let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10**18); // USD / USD/POLY = POLY + let investment_ETH_high = investment_USD.div(high_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_high = investment_USD.div(high_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY + let investment_ETH_low = investment_USD.div(low_USDETH).mul(10 ** 18); // USD / USD/ETH = ETH + let investment_POLY_low = investment_USD.div(low_USDPOLY).mul(10 ** 18); // USD / USD/POLY = POLY await I_PolyToken.getTokens(investment_POLY_low, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY_low, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY_low, { from: ACCREDITED1 }); // Change exchange rates up await I_USDOracle.changePrice(high_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(high_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_high, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_high, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_high, gasPrice: GAS_PRICE }) + ); // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_high, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); // Change exchange rates down await I_USDOracle.changePrice(low_USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(low_USDPOLY, { from: POLYMATH }); // Buy with ETH NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH_low, + gasPrice: GAS_PRICE + }) + ); // Buy with POLY NONACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY_low, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); // Buy with ETH ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH_low, gasPrice: GAS_PRICE }) + ); // Buy with POLY ACCREDITED - - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE })); + + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY_low, { from: ACCREDITED1, gasPrice: GAS_PRICE }) + ); // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); @@ -1957,86 +2927,121 @@ contract('USDTieredSTO', accounts => { }); }); - describe("Test getter functions", async() => { - - describe("Generic", async() => { - - it("should get the right number of investors", async() => { - assert.equal((await I_USDTieredSTO_Array[0].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[0].investorCount()).toNumber(), "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[1].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[1].investorCount()).toNumber(), "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[2].investorCount.call()).toNumber(), (await I_USDTieredSTO_Array[2].investorCount()).toNumber(), "Investor count not changed as expected"); + describe("Test getter functions", async () => { + describe("Generic", async () => { + it("should get the right number of investors", async () => { + assert.equal( + (await I_USDTieredSTO_Array[0].investorCount.call()).toNumber(), + (await I_USDTieredSTO_Array[0].investorCount()).toNumber(), + "Investor count not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[1].investorCount.call()).toNumber(), + (await I_USDTieredSTO_Array[1].investorCount()).toNumber(), + "Investor count not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[2].investorCount.call()).toNumber(), + (await I_USDTieredSTO_Array[2].investorCount()).toNumber(), + "Investor count not changed as expected" + ); }); - it("should get the right amounts invested", async() => { - assert.equal((await I_USDTieredSTO_Array[0].fundsRaised.call(ETH)).toNumber(), (await I_USDTieredSTO_Array[0].getRaised(0)).toNumber(), "getRaisedEther not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[0].fundsRaised.call(POLY)).toNumber(), (await I_USDTieredSTO_Array[0].getRaised(1)).toNumber(), "getRaisedPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[0].fundsRaisedUSD.call()).toNumber(), (await I_USDTieredSTO_Array[0].fundsRaisedUSD()).toNumber(), "fundsRaisedUSD not changed as expected"); + it("should get the right amounts invested", async () => { + assert.equal( + (await I_USDTieredSTO_Array[0].fundsRaised.call(ETH)).toNumber(), + (await I_USDTieredSTO_Array[0].getRaised(0)).toNumber(), + "getRaisedEther not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[0].fundsRaised.call(POLY)).toNumber(), + (await I_USDTieredSTO_Array[0].getRaised(1)).toNumber(), + "getRaisedPOLY not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[0].fundsRaisedUSD.call()).toNumber(), + (await I_USDTieredSTO_Array[0].fundsRaisedUSD()).toNumber(), + "fundsRaisedUSD not changed as expected" + ); }); }); - describe("convertToUSD", async() => { - - it("should reset exchange rates", async() => { + describe("convertToUSD", async () => { + it("should reset exchange rates", async () => { // Reset exchange rates await I_USDOracle.changePrice(USDETH, { from: POLYMATH }); await I_POLYOracle.changePrice(USDPOLY, { from: POLYMATH }); }); - it("should get the right conversion for ETH to USD", async() => { + it("should get the right conversion for ETH to USD", async () => { // 20 ETH to 10000 USD - let ethInWei = BigNumber(web3.utils.toWei('20', 'ether')); + let ethInWei = BigNumber(web3.utils.toWei("20", "ether")); let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(ETH, ethInWei); - assert.equal(usdInWei.div(10**18).toNumber(), ethInWei.div(10**18).mul(USDETH.div(10**18)).toNumber()); + assert.equal( + usdInWei.div(10 ** 18).toNumber(), + ethInWei + .div(10 ** 18) + .mul(USDETH.div(10 ** 18)) + .toNumber() + ); }); - it("should get the right conversion for POLY to USD", async() => { + it("should get the right conversion for POLY to USD", async () => { // 40000 POLY to 10000 USD - let polyInWei = BigNumber(web3.utils.toWei('40000', 'ether')); + let polyInWei = BigNumber(web3.utils.toWei("40000", "ether")); let usdInWei = await I_USDTieredSTO_Array[0].convertToUSD(POLY, polyInWei); - assert.equal(usdInWei.div(10**18).toNumber(), polyInWei.div(10**18).mul(USDPOLY.div(10**18)).toNumber()); + assert.equal( + usdInWei.div(10 ** 18).toNumber(), + polyInWei + .div(10 ** 18) + .mul(USDPOLY.div(10 ** 18)) + .toNumber() + ); }); }); - describe("convertFromUSD", async() => { - - it("should get the right conversion for USD to ETH", async() => { + describe("convertFromUSD", async () => { + it("should get the right conversion for USD to ETH", async () => { // 10000 USD to 20 ETH - let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); + let usdInWei = BigNumber(web3.utils.toWei("10000", "ether")); let ethInWei = await I_USDTieredSTO_Array[0].convertFromUSD(ETH, usdInWei); - assert.equal(ethInWei.div(10**18).toNumber(), usdInWei.div(10**18).div(USDETH.div(10**18)).toNumber()); + assert.equal( + ethInWei.div(10 ** 18).toNumber(), + usdInWei + .div(10 ** 18) + .div(USDETH.div(10 ** 18)) + .toNumber() + ); }); - it("should get the right conversion for USD to POLY", async() => { + it("should get the right conversion for USD to POLY", async () => { // 10000 USD to 40000 POLY - let usdInWei = BigNumber(web3.utils.toWei('10000', 'ether')); + let usdInWei = BigNumber(web3.utils.toWei("10000", "ether")); let polyInWei = await I_USDTieredSTO_Array[0].convertFromUSD(POLY, usdInWei); - assert.equal(polyInWei.div(10**18).toNumber(), usdInWei.div(10**18).div(USDPOLY.div(10**18)).toNumber()); + assert.equal( + polyInWei.div(10 ** 18).toNumber(), + usdInWei + .div(10 ** 18) + .div(USDPOLY.div(10 ** 18)) + .toNumber() + ); }); }); }); - describe("Test cases for the USDTieredSTOFactory", async() => { - it("should get the exact details of the factory", async() => { + describe("Test cases for the USDTieredSTOFactory", async () => { + it("should get the exact details of the factory", async () => { assert.equal((await I_USDTieredSTOFactory.setupCost.call()).toNumber(), STOSetupCost); - assert.equal((await I_USDTieredSTOFactory.getTypes.call())[0],3); - assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), - "USDTieredSTO", - "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.getDescription.call(), - "USD Tiered STO", - "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.getTitle.call(), - "USD Tiered STO", - "Wrong Module added"); - assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), - "Initialises a USD tiered STO.", - "Wrong Module added"); + assert.equal((await I_USDTieredSTOFactory.getTypes.call())[0], 3); + assert.equal(web3.utils.hexToString(await I_USDTieredSTOFactory.getName.call()), "USDTieredSTO", "Wrong Module added"); + assert.equal(await I_USDTieredSTOFactory.getDescription.call(), "USD Tiered STO", "Wrong Module added"); + assert.equal(await I_USDTieredSTOFactory.getTitle.call(), "USD Tiered STO", "Wrong Module added"); + assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), "Initialises a USD tiered STO.", "Wrong Module added"); let tags = await I_USDTieredSTOFactory.getTags.call(); - assert.equal(web3.utils.hexToString(tags[0]),"USD"); - assert.equal(web3.utils.hexToString(tags[1]),"Tiered"); - assert.equal(web3.utils.hexToString(tags[2]),"POLY"); - assert.equal(web3.utils.hexToString(tags[3]),"ETH"); - + assert.equal(web3.utils.hexToString(tags[0]), "USD"); + assert.equal(web3.utils.hexToString(tags[1]), "Tiered"); + assert.equal(web3.utils.hexToString(tags[2]), "POLY"); + assert.equal(web3.utils.hexToString(tags[3]), "ETH"); }); - }); + }); }); diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index 094ed97bd..ffc772631 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -1,34 +1,34 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); -const USDTieredSTO = artifacts.require('./USDTieredSTO.sol'); -const MockOracle = artifacts.require('./MockOracle.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); -const STFactory = artifacts.require('./STFactory.sol'); -const USDTieredSTOProxyFactory = artifacts.require('./USDTieredSTOProxyFactory'); -const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); -const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); +const USDTieredSTO = artifacts.require("./USDTieredSTO.sol"); +const MockOracle = artifacts.require("./MockOracle.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); +const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); +const STFactory = artifacts.require("./STFactory.sol"); +const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory"); +const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); +const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port const TOLERANCE = 2; // Allow balances to be off by 2 WEI for rounding purposes -contract('USDTieredSTO Sim', accounts => { +contract("USDTieredSTO Sim", accounts => { // Accounts Variable declaration let POLYMATH; let ISSUER; @@ -83,11 +83,11 @@ contract('USDTieredSTO Sim', accounts => { const STOSetupCost = 0; // MockOracle USD prices - const USDETH = BigNumber(500).mul(10**18); // 500 USD/ETH - const USDPOLY = BigNumber(25).mul(10**16); // 0.25 USD/POLY + const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH + const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; // STO Configuration Arrays let _startTime = []; @@ -118,52 +118,65 @@ contract('USDTieredSTO Sim', accounts => { address _usdToken ) */ const functionSignature = { - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_startTime' - },{ - type: 'uint256', - name: '_endTime' - },{ - type: 'uint256[]', - name: '_ratePerTier' - },{ - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - },{ - type: 'uint256[]', - name: '_tokensPerTier' - },{ - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - },{ - type: 'uint256', - name: '_nonAccreditedLimitUSD' - },{ - type: 'uint256', - name: '_minimumInvestmentUSD' - },{ - type: 'uint8[]', - name: '_fundRaiseTypes' - },{ - type: 'address', - name: '_wallet' - },{ - type: 'address', - name: '_reserveWallet' - },{ - type: 'address', - name: '_usdToken' - }] + name: "configure", + type: "function", + inputs: [ + { + type: "uint256", + name: "_startTime" + }, + { + type: "uint256", + name: "_endTime" + }, + { + type: "uint256[]", + name: "_ratePerTier" + }, + { + type: "uint256[]", + name: "_ratePerTierDiscountPoly" + }, + { + type: "uint256[]", + name: "_tokensPerTier" + }, + { + type: "uint256[]", + name: "_tokensPerTierDiscountPoly" + }, + { + type: "uint256", + name: "_nonAccreditedLimitUSD" + }, + { + type: "uint256", + name: "_minimumInvestmentUSD" + }, + { + type: "uint8[]", + name: "_fundRaiseTypes" + }, + { + type: "address", + name: "_wallet" + }, + { + type: "address", + name: "_reserveWallet" + }, + { + type: "address", + name: "_usdToken" + } + ] }; function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } - before(async() => { + before(async () => { // Accounts setup POLYMATH = accounts[0]; ISSUER = accounts[1]; @@ -177,34 +190,31 @@ contract('USDTieredSTO Sim', accounts => { NOTAPPROVED = accounts[8]; INVESTOR1 = accounts[9]; - // ----------- POLYMATH NETWORK Configuration ------------ + // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); + I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), ISSUER); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: POLYMATH - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: POLYMATH + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); + I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - // STEP 3: Deploy the GeneralTransferManagerFactory I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); @@ -225,53 +235,56 @@ contract('USDTieredSTO Sim', accounts => { "GeneralDelegateManagerFactory contract was not deployed" ); - // STEP 5: Deploy the proxy - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - - // STEP 6: Deploy the USDTieredSTOFactory + // STEP 5: Deploy the proxy + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: ISSUER }); - - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "USDTieredSTOFactory contract was not deployed" - ); + // STEP 6: Deploy the USDTieredSTOFactory + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { + from: ISSUER + }); + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "USDTieredSTOFactory contract was not deployed" + ); // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // Step 9: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + REGFEE, + REGFEE, + I_PolyToken.address, + POLYMATH + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: POLYMATH}); - await I_MRProxied.updateFromRegistry({from: POLYMATH}); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: POLYMATH }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); + await I_MRProxied.updateFromRegistry({ from: POLYMATH }); // STEP 7: Register the Modules with the ModuleRegistry contract @@ -315,12 +328,11 @@ contract('USDTieredSTO Sim', accounts => { `); }); - describe("Deploy the STO", async() => { - + describe("Deploy the STO", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.getTokens(REGFEE, ISSUER); await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); - let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from : ISSUER }); + let tx = await I_STRProxied.registerTicker(ISSUER, SYMBOL, NAME, { from: ISSUER }); assert.equal(tx.logs[0].args._owner, ISSUER); assert.equal(tx.logs[0].args._ticker, SYMBOL); }); @@ -334,17 +346,16 @@ contract('USDTieredSTO Sim', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), TMKEY); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(TMKEY))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(TMKEY))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the first STO module to the security token", async () => { @@ -352,55 +363,88 @@ contract('USDTieredSTO Sim', accounts => { _startTime.push(latestTime() + duration.days(2)); _endTime.push(_startTime[stoId] + duration.days(100)); - _ratePerTier.push([ - BigNumber(0.05*10**18), BigNumber(0.13*10**18), BigNumber(0.17*10**18) - ]); // [ 0.05 USD/Token, 0.10 USD/Token, 0.15 USD/Token ] - _ratePerTierDiscountPoly.push([ - BigNumber(0.05*10**18), BigNumber(0.08*10**18), BigNumber(0.13*10**18) - ]); // [ 0.05 USD/Token, 0.08 USD/Token, 0.13 USD/Token ] - _tokensPerTierTotal.push([ - BigNumber(200*10**18), BigNumber(500*10**18), BigNumber(300*10**18) - ]); // [ 1000 Token, 2000 Token, 1500 Token ] - _tokensPerTierDiscountPoly.push([ - BigNumber(0), BigNumber(50*10**18), BigNumber(300*10**18) - ]); // [ 0 Token, 1000 Token, 1500 Token ] - _nonAccreditedLimitUSD.push(BigNumber(10*10**18)); // 20 USD - _minimumInvestmentUSD.push(BigNumber(0)); // 1 wei USD - _fundRaiseTypes.push([0,1,2]); + _ratePerTier.push([BigNumber(0.05 * 10 ** 18), BigNumber(0.13 * 10 ** 18), BigNumber(0.17 * 10 ** 18)]); // [ 0.05 USD/Token, 0.10 USD/Token, 0.15 USD/Token ] + _ratePerTierDiscountPoly.push([BigNumber(0.05 * 10 ** 18), BigNumber(0.08 * 10 ** 18), BigNumber(0.13 * 10 ** 18)]); // [ 0.05 USD/Token, 0.08 USD/Token, 0.13 USD/Token ] + _tokensPerTierTotal.push([BigNumber(200 * 10 ** 18), BigNumber(500 * 10 ** 18), BigNumber(300 * 10 ** 18)]); // [ 1000 Token, 2000 Token, 1500 Token ] + _tokensPerTierDiscountPoly.push([BigNumber(0), BigNumber(50 * 10 ** 18), BigNumber(300 * 10 ** 18)]); // [ 0 Token, 1000 Token, 1500 Token ] + _nonAccreditedLimitUSD.push(BigNumber(10 * 10 ** 18)); // 20 USD + _minimumInvestmentUSD.push(BigNumber(0)); // 1 wei USD + _fundRaiseTypes.push([0, 1, 2]); _wallet.push(WALLET); _reserveWallet.push(RESERVEWALLET); _usdToken.push(I_DaiToken.address); let config = [ - _startTime[stoId], _endTime[stoId], _ratePerTier[stoId], _ratePerTierDiscountPoly[stoId], _tokensPerTierTotal[stoId], - _tokensPerTierDiscountPoly[stoId], _nonAccreditedLimitUSD[stoId], _minimumInvestmentUSD[stoId], - _fundRaiseTypes[stoId], _wallet[stoId], _reserveWallet[stoId], _usdToken[stoId] + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); - console.log(" Gas addModule: ".grey+tx.receipt.gasUsed.toString().grey); + console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); I_USDTieredSTO_Array.push(USDTieredSTO.at(tx.logs[2].args._module)); - assert.equal((await I_USDTieredSTO_Array[stoId].startTime.call()), _startTime[stoId], "Incorrect _startTime in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].endTime.call()), _endTime[stoId], "Incorrect _endTime in config"); + assert.equal(await I_USDTieredSTO_Array[stoId].startTime.call(), _startTime[stoId], "Incorrect _startTime in config"); + assert.equal(await I_USDTieredSTO_Array[stoId].endTime.call(), _endTime[stoId], "Incorrect _endTime in config"); for (var i = 0; i < _ratePerTier[stoId].length; i++) { - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), _ratePerTier[stoId][i].toNumber(), "Incorrect _ratePerTier in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), _ratePerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _ratePerTierDiscountPoly in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), _tokensPerTierTotal[stoId][i].toNumber(), "Incorrect _tokensPerTierTotal in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), _tokensPerTierDiscountPoly[stoId][i].toNumber(), "Incorrect _tokensPerTierDiscountPoly in config"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTier.call(i)).toNumber(), + _ratePerTier[stoId][i].toNumber(), + "Incorrect _ratePerTier in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].ratePerTierDiscountPoly.call(i)).toNumber(), + _ratePerTierDiscountPoly[stoId][i].toNumber(), + "Incorrect _ratePerTierDiscountPoly in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).toNumber(), + _tokensPerTierTotal[stoId][i].toNumber(), + "Incorrect _tokensPerTierTotal in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).toNumber(), + _tokensPerTierDiscountPoly[stoId][i].toNumber(), + "Incorrect _tokensPerTierDiscountPoly in config" + ); } - assert.equal((await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), _nonAccreditedLimitUSD[stoId].toNumber(), "Incorrect _nonAccreditedLimitUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), _minimumInvestmentUSD[stoId].toNumber(), "Incorrect _minimumInvestmentUSD in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].wallet.call()), _wallet[stoId], "Incorrect _wallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].reserveWallet.call()), _reserveWallet[stoId], "Incorrect _reserveWallet in config"); - assert.equal((await I_USDTieredSTO_Array[stoId].getNumberOfTiers()), _tokensPerTierTotal[stoId].length, "Incorrect number of tiers"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSD.call()).toNumber(), + _nonAccreditedLimitUSD[stoId].toNumber(), + "Incorrect _nonAccreditedLimitUSD in config" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].minimumInvestmentUSD.call()).toNumber(), + _minimumInvestmentUSD[stoId].toNumber(), + "Incorrect _minimumInvestmentUSD in config" + ); + assert.equal(await I_USDTieredSTO_Array[stoId].wallet.call(), _wallet[stoId], "Incorrect _wallet in config"); + assert.equal( + await I_USDTieredSTO_Array[stoId].reserveWallet.call(), + _reserveWallet[stoId], + "Incorrect _reserveWallet in config" + ); + assert.equal( + await I_USDTieredSTO_Array[stoId].getNumberOfTiers(), + _tokensPerTierTotal[stoId].length, + "Incorrect number of tiers" + ); assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); }); - it("Should successfully prepare the STO", async() => { + it("Should successfully prepare the STO", async () => { let stoId = 0; // Start STO @@ -426,9 +470,8 @@ contract('USDTieredSTO Sim', accounts => { }); }); - describe("Simulate purchasing", async() => { - - it("Should successfully complete simulation", async() => { + describe("Simulate purchasing", async () => { + it("Should successfully complete simulation", async () => { let stoId = 0; console.log(` @@ -446,10 +489,10 @@ contract('USDTieredSTO Sim', accounts => { for (var i = 0; i < _tokensPerTierTotal[stoId].length; i++) { totalTokens = totalTokens.add(_tokensPerTierTotal[stoId][i]); } - console.log('totalTokens: '+totalTokens.div(10**18).toNumber()); + console.log("totalTokens: " + totalTokens.div(10 ** 18).toNumber()); let tokensSold = BigNumber(0); while (true) { - switch (getRandomInt(0,5)) { + switch (getRandomInt(0, 5)) { case 0: // ACCREDITED1 await invest(ACCREDITED1, true); break; @@ -458,17 +501,19 @@ contract('USDTieredSTO Sim', accounts => { break; case 2: // NONACCREDITED1 let usd_NONACCREDITED1 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); - if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED1)) // under non-accredited cap + if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED1)) + // under non-accredited cap await invest(NONACCREDITED1, false); - else // over non-accredited cap - await investFAIL(NONACCREDITED1); + // over non-accredited cap + else await investFAIL(NONACCREDITED1); break; case 3: // NONACCREDITED2 let usd_NONACCREDITED2 = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED2); - if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED2)) // under non-accredited cap + if (_nonAccreditedLimitUSD[stoId].gt(usd_NONACCREDITED2)) + // under non-accredited cap await invest(NONACCREDITED2, false); - else // over non-accredited cap - await investFAIL(NONACCREDITED2); + // over non-accredited cap + else await investFAIL(NONACCREDITED2); break; case 4: // NOTWHITELISTED await investFAIL(NOTWHITELISTED); @@ -480,13 +525,14 @@ contract('USDTieredSTO Sim', accounts => { console.log("Next round"); tokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); console.log("Tokens Sold: " + tokensSold.toString()); - if (tokensSold.gte(totalTokens.sub(1*10**18))) { + if (tokensSold.gte(totalTokens.sub(1 * 10 ** 18))) { console.log(`${tokensSold} tokens sold, simulation completed successfully!`.green); break; } } - async function invest(_investor, _isAccredited) { // need to add check if reached non-accredited cap + async function invest(_investor, _isAccredited) { + // need to add check if reached non-accredited cap let USD_remaining; if (!_isAccredited) { let USD_to_date = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(_investor); @@ -499,7 +545,7 @@ contract('USDTieredSTO Sim', accounts => { let isPoly = Math.random() >= 0.33; let isDai = Math.random() >= 0.33; - let Token_counter = BigNumber(getRandomInt(1*10**10,50*10**10)).mul(10**8); + let Token_counter = BigNumber(getRandomInt(1 * 10 ** 10, 50 * 10 ** 10)).mul(10 ** 8); let investment_USD = BigNumber(0); let investment_ETH = BigNumber(0); let investment_POLY = BigNumber(0); @@ -509,8 +555,16 @@ contract('USDTieredSTO Sim', accounts => { let Tokens_total = []; let Tokens_discount = []; for (var i = 0; i < _ratePerTier[stoId].length; i++) { - Tokens_total.push((await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(i))); - Tokens_discount.push((await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).sub(await I_USDTieredSTO_Array[stoId].mintedPerTierDiscountPoly.call(i))); + Tokens_total.push( + (await I_USDTieredSTO_Array[stoId].tokensPerTierTotal.call(i)).sub( + await I_USDTieredSTO_Array[stoId].mintedPerTierTotal.call(i) + ) + ); + Tokens_discount.push( + (await I_USDTieredSTO_Array[stoId].tokensPerTierDiscountPoly.call(i)).sub( + await I_USDTieredSTO_Array[stoId].mintedPerTierDiscountPoly.call(i) + ) + ); } let tier = 0; @@ -520,7 +574,6 @@ contract('USDTieredSTO Sim', accounts => { let ETH_Tier; let DAI_Tier; - let USD_overflow; let Token_overflow; @@ -533,15 +586,18 @@ contract('USDTieredSTO Sim', accounts => { // 1. POLY and discount (consume up to cap then move to regular) if (Tokens_discount[tier].gt(0)) { Token_Tier = BigNumber.min([Tokens_total[tier], Tokens_discount[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTierDiscountPoly[stoId][tier].div(10**18)); + USD_Tier = Token_Tier.mul(_ratePerTierDiscountPoly[stoId][tier].div(10 ** 18)); if (USD_Tier.gte(USD_remaining)) { USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTierDiscountPoly[stoId][tier]); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTierDiscountPoly[stoId][tier]); USD_Tier = USD_Tier.sub(USD_overflow); Token_Tier = Token_Tier.sub(Token_overflow); Token_counter = BigNumber(0); } - POLY_Tier = USD_Tier.mul(10**18).round(0).div(USDPOLY).round(0); + POLY_Tier = USD_Tier.mul(10 ** 18) + .round(0) + .div(USDPOLY) + .round(0); USD_remaining = USD_remaining.sub(USD_Tier); Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); Tokens_discount[tier] = Tokens_discount[tier].sub(Token_Tier); @@ -553,15 +609,18 @@ contract('USDTieredSTO Sim', accounts => { // 2. POLY and regular (consume up to cap then skip to next tier) if (Tokens_total[tier].gt(0) && Token_counter.gt(0)) { Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); if (USD_Tier.gte(USD_remaining)) { USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); USD_Tier = USD_Tier.sub(USD_overflow); Token_Tier = Token_Tier.sub(Token_overflow); Token_counter = BigNumber(0); } - POLY_Tier = USD_Tier.mul(10**18).round(0).div(USDPOLY).round(0); + POLY_Tier = USD_Tier.mul(10 ** 18) + .round(0) + .div(USDPOLY) + .round(0); USD_remaining = USD_remaining.sub(USD_Tier); Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); Token_counter = Token_counter.sub(Token_Tier); @@ -572,10 +631,10 @@ contract('USDTieredSTO Sim', accounts => { } else if (isDai) { // 3. DAI (consume up to cap then skip to next tier) Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); if (USD_Tier.gte(USD_remaining)) { USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); USD_Tier = USD_Tier.sub(USD_overflow); Token_Tier = Token_Tier.sub(Token_overflow); Token_counter = BigNumber(0); @@ -590,15 +649,18 @@ contract('USDTieredSTO Sim', accounts => { } else { // 4. ETH (consume up to cap then skip to next tier) Token_Tier = BigNumber.min([Tokens_total[tier], Token_counter]); - USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10**18)); + USD_Tier = Token_Tier.mul(_ratePerTier[stoId][tier].div(10 ** 18)); if (USD_Tier.gte(USD_remaining)) { USD_overflow = USD_Tier.sub(USD_remaining); - Token_overflow = USD_overflow.mul(10**18).div(_ratePerTier[stoId][tier]); + Token_overflow = USD_overflow.mul(10 ** 18).div(_ratePerTier[stoId][tier]); USD_Tier = USD_Tier.sub(USD_overflow); Token_Tier = Token_Tier.sub(Token_overflow); Token_counter = BigNumber(0); } - ETH_Tier = USD_Tier.mul(10**18).round(0).div(USDETH).round(0); + ETH_Tier = USD_Tier.mul(10 ** 18) + .round(0) + .div(USDETH) + .round(0); USD_remaining = USD_remaining.sub(USD_Tier); Tokens_total[tier] = Tokens_total[tier].sub(Token_Tier); Token_counter = Token_counter.sub(Token_Tier); @@ -607,50 +669,75 @@ contract('USDTieredSTO Sim', accounts => { investment_ETH = investment_ETH.add(ETH_Tier); } } - tier++ + tier++; } - await processInvestment(_investor, investment_Token, investment_USD, investment_POLY, investment_DAI, investment_ETH, isPoly, isDai, log_remaining, Tokens_total, Tokens_discount, tokensSold); + await processInvestment( + _investor, + investment_Token, + investment_USD, + investment_POLY, + investment_DAI, + investment_ETH, + isPoly, + isDai, + log_remaining, + Tokens_total, + Tokens_discount, + tokensSold + ); } async function investFAIL(_investor) { let isPoly = Math.random() >= 0.3; let isDAI = Math.random() >= 0.3; - let investment_POLY = BigNumber(40*10**18); // 10 USD = 40 POLY - let investment_ETH = BigNumber(0.02*10**18); // 10 USD = 0.02 ETH - let investment_DAI = BigNumber(10*10**18); // 10 USD = DAI DAI + let investment_POLY = BigNumber(40 * 10 ** 18); // 10 USD = 40 POLY + let investment_ETH = BigNumber(0.02 * 10 ** 18); // 10 USD = 0.02 ETH + let investment_DAI = BigNumber(10 * 10 ** 18); // 10 USD = DAI DAI - await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); } - async function processInvestment(_investor, investment_Token, investment_USD, investment_POLY, investment_DAI, investment_ETH, isPoly, isDai, log_remaining, Tokens_total, Tokens_discount, tokensSold) { - investment_Token = investment_Token.round(0); - investment_USD = investment_USD.round(0); - investment_POLY = investment_POLY.round(0); - investment_DAI = investment_DAI.round(0); - investment_ETH = investment_ETH.round(0); + async function processInvestment( + _investor, + investment_Token, + investment_USD, + investment_POLY, + investment_DAI, + investment_ETH, + isPoly, + isDai, + log_remaining, + Tokens_total, + Tokens_discount, + tokensSold + ) { + investment_Token = investment_Token.round(0); + investment_USD = investment_USD.round(0); + investment_POLY = investment_POLY.round(0); + investment_DAI = investment_DAI.round(0); + investment_ETH = investment_ETH.round(0); console.log(` ------------------- New Investment ------------------- Investor: ${_investor} - N-A USD Remaining: ${log_remaining.div(10**18)} + N-A USD Remaining: ${log_remaining.div(10 ** 18)} Total Cap Remaining: ${Tokens_total} Discount Cap Remaining: ${Tokens_discount} - Total Tokens Sold: ${tokensSold.div(10**18)} - Token Investment: ${investment_Token.div(10**18)} - USD Investment: ${investment_USD.div(10**18)} - POLY Investment: ${investment_POLY.div(10**18)} - DAI Investment: ${investment_DAI.div(10**18)} - ETH Investment: ${investment_ETH.div(10**18)} + Total Tokens Sold: ${tokensSold.div(10 ** 18)} + Token Investment: ${investment_Token.div(10 ** 18)} + USD Investment: ${investment_USD.div(10 ** 18)} + POLY Investment: ${investment_POLY.div(10 ** 18)} + DAI Investment: ${investment_DAI.div(10 ** 18)} + ETH Investment: ${investment_ETH.div(10 ** 18)} ------------------------------------------------------ `); if (isPoly) { await I_PolyToken.getTokens(investment_POLY, _investor); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: _investor}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: _investor }); } else if (isDai) { await I_DaiToken.getTokens(investment_DAI, _investor); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: _investor}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: _investor }); } // console.log(await I_USDTieredSTO_Array[stoId].isOpen()); @@ -676,17 +763,33 @@ contract('USDTieredSTO Sim', accounts => { let gasCost = BigNumber(0); if (isPoly && investment_POLY.gt(10)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE }); + tx = await I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { + from: _investor, + gasPrice: GAS_PRICE + }); gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log(`buyWithPOLY: ${investment_Token.div(10**18)} tokens for ${investment_POLY.div(10**18)} POLY by ${_investor}`.yellow); + console.log( + `buyWithPOLY: ${investment_Token.div(10 ** 18)} tokens for ${investment_POLY.div(10 ** 18)} POLY by ${_investor}` + .yellow + ); } else if (isDai && investment_DAI.gt(10)) { tx = await I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE }); gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log(`buyWithUSD: ${investment_Token.div(10**18)} tokens for ${investment_DAI.div(10**18)} DAI by ${_investor}`.yellow); + console.log( + `buyWithUSD: ${investment_Token.div(10 ** 18)} tokens for ${investment_DAI.div(10 ** 18)} DAI by ${_investor}` + .yellow + ); } else if (investment_ETH.gt(0)) { - tx = await I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE }); + tx = await I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { + from: _investor, + value: investment_ETH, + gasPrice: GAS_PRICE + }); gasCost = BigNumber(GAS_PRICE).mul(tx.receipt.gasUsed); - console.log(`buyWithETH: ${investment_Token.div(10**18)} tokens for ${investment_ETH.div(10**18)} ETH by ${_investor}`.yellow); + console.log( + `buyWithETH: ${investment_Token.div(10 ** 18)} tokens for ${investment_ETH.div(10 ** 18)} ETH by ${_investor}` + .yellow + ); } console.log(investment_POLY.toNumber()); @@ -711,44 +814,217 @@ contract('USDTieredSTO Sim', accounts => { // console.log('final_TokenSupply: '+final_TokenSupply.div(10**18).toNumber()); if (isPoly) { - assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); - assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); - assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); - assert.closeTo(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), TOLERANCE, "Investor POLY Balance not changed as expected"); - assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); - assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, "STO POLY Balance not changed as expected"); - assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); + assert.closeTo( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + TOLERANCE, + "Token Supply not changed as expected" + ); + assert.closeTo( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + TOLERANCE, + "Investor Token Balance not changed as expected" + ); + assert.closeTo( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost).toNumber(), + TOLERANCE, + "Investor ETH Balance not changed as expected" + ); + assert.closeTo( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + TOLERANCE, + "Investor POLY Balance not changed as expected" + ); + assert.closeTo( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + TOLERANCE, + "STO Token Sold not changed as expected" + ); + assert.closeTo( + final_STOETHBal.toNumber(), + init_STOETHBal.toNumber(), + TOLERANCE, + "STO ETH Balance not changed as expected" + ); + assert.closeTo( + final_STOPOLYBal.toNumber(), + init_STOPOLYBal.toNumber(), + TOLERANCE, + "STO POLY Balance not changed as expected" + ); + assert.closeTo( + final_RaisedUSD.toNumber(), + init_RaisedUSD.add(investment_USD).toNumber(), + TOLERANCE, + "Raised USD not changed as expected" + ); assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, "Raised ETH not changed as expected"); - assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), TOLERANCE, "Raised POLY not changed as expected"); - assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); - assert.closeTo(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), TOLERANCE, "Wallet POLY Balance not changed as expected"); + assert.closeTo( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + TOLERANCE, + "Raised POLY not changed as expected" + ); + assert.closeTo( + final_WalletETHBal.toNumber(), + init_WalletETHBal.toNumber(), + TOLERANCE, + "Wallet ETH Balance not changed as expected" + ); + assert.closeTo( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + TOLERANCE, + "Wallet POLY Balance not changed as expected" + ); } else if (isDai) { - assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); - assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); - assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); - assert.closeTo(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), TOLERANCE, "Investor DAI Balance not changed as expected"); - assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); - assert.closeTo(final_STODAIBal.toNumber(), init_STODAIBal.toNumber(), TOLERANCE, "STO DAI Balance not changed as expected"); - assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); + assert.closeTo( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + TOLERANCE, + "Token Supply not changed as expected" + ); + assert.closeTo( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + TOLERANCE, + "Investor Token Balance not changed as expected" + ); + assert.closeTo( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost).toNumber(), + TOLERANCE, + "Investor ETH Balance not changed as expected" + ); + assert.closeTo( + final_InvestorDAIBal.toNumber(), + init_InvestorDAIBal.sub(investment_DAI).toNumber(), + TOLERANCE, + "Investor DAI Balance not changed as expected" + ); + assert.closeTo( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + TOLERANCE, + "STO Token Sold not changed as expected" + ); + assert.closeTo( + final_STOETHBal.toNumber(), + init_STOETHBal.toNumber(), + TOLERANCE, + "STO ETH Balance not changed as expected" + ); + assert.closeTo( + final_STODAIBal.toNumber(), + init_STODAIBal.toNumber(), + TOLERANCE, + "STO DAI Balance not changed as expected" + ); + assert.closeTo( + final_RaisedUSD.toNumber(), + init_RaisedUSD.add(investment_USD).toNumber(), + TOLERANCE, + "Raised USD not changed as expected" + ); assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), TOLERANCE, "Raised ETH not changed as expected"); - assert.closeTo(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), TOLERANCE, "Raised DAI not changed as expected"); - assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); - assert.closeTo(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), TOLERANCE, "Wallet DAI Balance not changed as expected"); + assert.closeTo( + final_RaisedDAI.toNumber(), + init_RaisedDAI.add(investment_DAI).toNumber(), + TOLERANCE, + "Raised DAI not changed as expected" + ); + assert.closeTo( + final_WalletETHBal.toNumber(), + init_WalletETHBal.toNumber(), + TOLERANCE, + "Wallet ETH Balance not changed as expected" + ); + assert.closeTo( + final_WalletDAIBal.toNumber(), + init_WalletDAIBal.add(investment_DAI).toNumber(), + TOLERANCE, + "Wallet DAI Balance not changed as expected" + ); } else { - assert.closeTo(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), TOLERANCE, "Token Supply not changed as expected"); - assert.closeTo(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), TOLERANCE, "Investor Token Balance not changed as expected"); - assert.closeTo(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost).sub(investment_ETH).toNumber(), TOLERANCE, "Investor ETH Balance not changed as expected"); - assert.closeTo(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), TOLERANCE, "Investor POLY Balance not changed as expected"); - assert.closeTo(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), TOLERANCE, "STO Token Sold not changed as expected"); - assert.closeTo(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), TOLERANCE, "STO ETH Balance not changed as expected"); - assert.closeTo(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), TOLERANCE, "STO POLY Balance not changed as expected"); - assert.closeTo(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), TOLERANCE, "Raised USD not changed as expected"); - assert.closeTo(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), TOLERANCE, "Raised ETH not changed as expected"); - assert.closeTo(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), TOLERANCE, "Raised POLY not changed as expected"); - assert.closeTo(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), TOLERANCE, "Wallet ETH Balance not changed as expected"); - assert.closeTo(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), TOLERANCE, "Wallet POLY Balance not changed as expected"); + assert.closeTo( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + TOLERANCE, + "Token Supply not changed as expected" + ); + assert.closeTo( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + TOLERANCE, + "Investor Token Balance not changed as expected" + ); + assert.closeTo( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost) + .sub(investment_ETH) + .toNumber(), + TOLERANCE, + "Investor ETH Balance not changed as expected" + ); + assert.closeTo( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + TOLERANCE, + "Investor POLY Balance not changed as expected" + ); + assert.closeTo( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + TOLERANCE, + "STO Token Sold not changed as expected" + ); + assert.closeTo( + final_STOETHBal.toNumber(), + init_STOETHBal.toNumber(), + TOLERANCE, + "STO ETH Balance not changed as expected" + ); + assert.closeTo( + final_STOPOLYBal.toNumber(), + init_STOPOLYBal.toNumber(), + TOLERANCE, + "STO POLY Balance not changed as expected" + ); + assert.closeTo( + final_RaisedUSD.toNumber(), + init_RaisedUSD.add(investment_USD).toNumber(), + TOLERANCE, + "Raised USD not changed as expected" + ); + assert.closeTo( + final_RaisedETH.toNumber(), + init_RaisedETH.add(investment_ETH).toNumber(), + TOLERANCE, + "Raised ETH not changed as expected" + ); + assert.closeTo( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.toNumber(), + TOLERANCE, + "Raised POLY not changed as expected" + ); + assert.closeTo( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + TOLERANCE, + "Wallet ETH Balance not changed as expected" + ); + assert.closeTo( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.toNumber(), + TOLERANCE, + "Wallet POLY Balance not changed as expected" + ); } } }); @@ -756,6 +1032,5 @@ contract('USDTieredSTO Sim', accounts => { }); function near(x, y, message) { - assert.isAtMost(x, y) - + assert.isAtMost(x, y); } diff --git a/test/r_concurrent_STO.js b/test/r_concurrent_STO.js index 569534cad..937378822 100644 --- a/test/r_concurrent_STO.js +++ b/test/r_concurrent_STO.js @@ -1,34 +1,34 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; // Import contract ABIs -const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); -const CappedSTO = artifacts.require('./CappedSTO.sol'); -const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); -const DummySTO = artifacts.require('./DummySTO.sol'); -const PreSaleSTOFactory = artifacts.require('./PreSaleSTOFactory.sol'); -const PreSaleSTO = artifacts.require('./PreSaleSTO.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('Concurrent STO', accounts => { +const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); +const CappedSTO = artifacts.require("./CappedSTO.sol"); +const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); +const DummySTO = artifacts.require("./DummySTO.sol"); +const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); +const PreSaleSTO = artifacts.require("./PreSaleSTO.sol"); +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("Concurrent STO", accounts => { // Accounts variable declaration let account_polymath; let account_issuer; @@ -73,50 +73,48 @@ contract('Concurrent STO', accounts => { // Configure function signature for STO deployment - const CappedSTOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const DummySTOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const PresaleSTOParameters = ['uint256']; + const CappedSTOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; + const DummySTOParameters = ["uint256", "uint256", "uint256", "string"]; + const PresaleSTOParameters = ["uint256"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; account_fundsReceiver = accounts[2]; account_investor1 = accounts[3]; account_investor2 = accounts[4]; - account_investor3 = accounts[5] + account_investor3 = accounts[5]; // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), account_issuer); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_issuer); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 2: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -126,7 +124,9 @@ contract('Concurrent STO', accounts => { // STEP 3: Deploy the GeneralPermissionManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -146,39 +146,43 @@ contract('Concurrent STO', accounts => { "CappedSTOFactory contract was not deployed" ); - // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // Step 9: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // STEP 5: Register the Modules with the ModuleRegistry contract @@ -220,7 +224,7 @@ contract('Concurrent STO', accounts => { `); }); - describe("Generate Security Token", async() => { + describe("Generate Security Token", async () => { // SecurityToken Details for funds raise Type ETH const name = "Team"; const symbol = "SAP"; @@ -230,57 +234,49 @@ contract('Concurrent STO', accounts => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.getTokens(initRegFee, account_issuer); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); - let tx = await I_STRProxied.registerTicker(account_issuer, symbol, name, { from : account_issuer }); + let tx = await I_STRProxied.registerTicker(account_issuer, symbol, name, { from: account_issuer }); assert.equal(tx.logs[0].args._owner, account_issuer); assert.equal(tx.logs[0].args._ticker, symbol); }); it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.getTokens(initRegFee, account_issuer); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); let _blockNo = latestBlock(); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_issuer }); assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { let moduleData = (await I_SecurityToken.getModulesByType(transferManagerKey))[0]; I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - it("Should whitelist account_investor1", async() => { + it("Should whitelist account_investor1", async () => { let fromTime = latestTime(); let toTime = latestTime() + duration.days(15); let expiryTime = toTime + duration.days(100); let canBuyFromSTO = true; - let tx = await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - fromTime, - toTime, - expiryTime, - canBuyFromSTO, - { - from: account_issuer, - gas: 500000 - }); + let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, canBuyFromSTO, { + from: account_issuer, + gas: 500000 + }); assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); }); }); - describe("Add STO and verify transfer", async() => { - - it("Should attach STO modules up to the max number, then fail", async() => { + describe("Add STO and verify transfer", async () => { + it("Should attach STO modules up to the max number, then fail", async () => { const MAX_MODULES = 10; const startTime = latestTime() + duration.days(1); const endTime = latestTime() + duration.days(90); @@ -289,8 +285,15 @@ contract('Concurrent STO', accounts => { const fundRaiseType = [0]; const budget = 0; const maxCost = STOSetupCost; - const cappedBytesSig = encodeModuleCall(CappedSTOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, 'Hello']); + const cappedBytesSig = encodeModuleCall(CappedSTOParameters, [ + startTime, + endTime, + cap, + rate, + fundRaiseType, + account_fundsReceiver + ]); + const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, "Hello"]); const presaleBytesSig = encodeModuleCall(PresaleSTOParameters, [endTime]); for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { @@ -299,62 +302,80 @@ contract('Concurrent STO', accounts => { switch (STOIndex % 3) { case 0: // Capped STO - let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { from: account_issuer }); + let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { + from: account_issuer + }); assert.equal(tx1.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx1.logs[3].args._name),"CappedSTO",`Wrong STO module added at index ${STOIndex}`); + assert.equal( + web3.utils.hexToString(tx1.logs[3].args._name), + "CappedSTO", + `Wrong STO module added at index ${STOIndex}` + ); I_STO_Array.push(CappedSTO.at(tx1.logs[3].args._module)); break; case 1: // Dummy STO - let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { from: account_issuer }); + let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { + from: account_issuer + }); assert.equal(tx2.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx2.logs[3].args._name),"DummySTO",`Wrong STO module added at index ${STOIndex}`); + assert.equal( + web3.utils.hexToString(tx2.logs[3].args._name), + "DummySTO", + `Wrong STO module added at index ${STOIndex}` + ); I_STO_Array.push(DummySTO.at(tx2.logs[3].args._module)); break; case 2: // Pre Sale STO - let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { from: account_issuer }); + let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { + from: account_issuer + }); assert.equal(tx3.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); - assert.equal(web3.utils.hexToString(tx3.logs[3].args._name),"PreSaleSTO",`Wrong STO module added at index ${STOIndex}`); + assert.equal( + web3.utils.hexToString(tx3.logs[3].args._name), + "PreSaleSTO", + `Wrong STO module added at index ${STOIndex}` + ); I_STO_Array.push(PreSaleSTO.at(tx3.logs[3].args._module)); break; } } - }); - it("Should successfully invest in all modules attached", async() => { + it("Should successfully invest in all modules attached", async () => { const MAX_MODULES = 10; await increaseTime(duration.days(2)); for (var STOIndex = 0; STOIndex < MAX_MODULES; STOIndex++) { switch (STOIndex % 3) { case 0: // Capped STO ETH - await I_STO_Array[STOIndex].buyTokens(account_investor1, { from : account_investor1, value: web3.utils.toWei('1', 'ether') }); + await I_STO_Array[STOIndex].buyTokens(account_investor1, { + from: account_investor1, + value: web3.utils.toWei("1", "ether") + }); assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); break; case 1: // Dummy STO - await I_STO_Array[STOIndex].generateTokens(account_investor1, web3.utils.toWei('1000'), { from : account_issuer }); + await I_STO_Array[STOIndex].generateTokens(account_investor1, web3.utils.toWei("1000"), { from: account_issuer }); assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); assert.equal( - (await I_STO_Array[STOIndex].investors.call(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_STO_Array[STOIndex].investors.call(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000 ); break; case 2: // Pre Sale STO - await I_STO_Array[STOIndex].allocateTokens(account_investor1, web3.utils.toWei('1000'), web3.utils.toWei('1'), 0, { from : account_issuer }); + await I_STO_Array[STOIndex].allocateTokens(account_investor1, web3.utils.toWei("1000"), web3.utils.toWei("1"), 0, { + from: account_issuer + }); assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(0)).toString()), 1); assert.equal(web3.utils.fromWei((await I_STO_Array[STOIndex].getRaised.call(1)).toString()), 0); assert.equal(await I_STO_Array[STOIndex].investorCount.call(), 1); assert.equal( - (await I_STO_Array[STOIndex].investors.call(account_investor1)) - .dividedBy(new BigNumber(10).pow(18)) - .toNumber(), + (await I_STO_Array[STOIndex].investors.call(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000 ); break; diff --git a/test/s_v130_to_v140_upgrade.js b/test/s_v130_to_v140_upgrade.js index f4dee4bf2..c5c9cb8fc 100644 --- a/test/s_v130_to_v140_upgrade.js +++ b/test/s_v130_to_v140_upgrade.js @@ -1,32 +1,32 @@ -const Web3 = require('web3'); +const Web3 = require("web3"); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port -const BigNumber = require('bignumber.js'); - -import latestTime from './helpers/latestTime'; -import { duration } from './helpers/utils'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const USDTieredSTOProxyFactory = artifacts.require('./USDTieredSTOProxyFactory.sol'); -const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); -const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol'); -const USDTieredSTO = artifacts.require('./USDTieredSTO.sol'); -const CappedSTO = artifacts.require('./CappedSTO.sol'); -const PolyOracle = artifacts.require('./PolyOracle.sol'); -const ETHOracle = artifacts.require('./MakerDAOOracle.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); -const ManualApprovalTransferManagerFactory = artifacts.require('./ManualApprovalTransferManagerFactory.sol'); - -contract('Upgrade from v1.3.0 to v1.4.0', accounts => { +const BigNumber = require("bignumber.js"); + +import latestTime from "./helpers/latestTime"; +import { duration } from "./helpers/utils"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory.sol"); +const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); +const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); +const USDTieredSTO = artifacts.require("./USDTieredSTO.sol"); +const CappedSTO = artifacts.require("./CappedSTO.sol"); +const PolyOracle = artifacts.require("./PolyOracle.sol"); +const ETHOracle = artifacts.require("./MakerDAOOracle.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); +const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); + +contract("Upgrade from v1.3.0 to v1.4.0", accounts => { // Accounts Variable declaration let POLYMATH; let ISSUER1; @@ -84,7 +84,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { //let I_SecurityToken3; let I_USDTieredSTOFactory; - let I_USDTieredSTOProxyFactory + let I_USDTieredSTOProxyFactory; let I_USDOracle; let I_POLYOracle; let I_USDTieredSTO; @@ -94,11 +94,11 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { let I_CappedSTO; let I_ManualApprovalTransferManagerFactory; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - const STOParameters = ['uint256', 'uint256', 'uint256', 'uint256', 'uint8[]', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; + const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; // Prepare polymath network status - before(async() => { + before(async () => { // Accounts setup POLYMATH = accounts[0]; ISSUER1 = accounts[1]; @@ -109,7 +109,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: POLYMATH}); + I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); assert.notEqual( I_PolymathRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -117,26 +117,22 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { ); // Step 1: Deploy the token Faucet - I_PolyToken = await PolyTokenFaucet.new({from: POLYMATH}); - I_DaiToken = await PolyTokenFaucet.new({from: POLYMATH}); - assert.notEqual( - I_PolyToken.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PolyToken contract was not deployed" - ); - tx = await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: POLYMATH}) + I_PolyToken = await PolyTokenFaucet.new({ from: POLYMATH }); + I_DaiToken = await PolyTokenFaucet.new({ from: POLYMATH }); + assert.notEqual(I_PolyToken.address.valueOf(), "0x0000000000000000000000000000000000000000", "PolyToken contract was not deployed"); + tx = await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: POLYMATH }); assert.equal(tx.logs[0].args._nameKey, "PolyToken"); assert.equal(tx.logs[0].args._newAddress, I_PolyToken.address); // STEP 2: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from: POLYMATH}); + I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: POLYMATH}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: POLYMATH}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - tx = await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: POLYMATH}); + tx = await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: POLYMATH }); assert.equal(tx.logs[0].args._nameKey, "ModuleRegistry"); assert.equal(tx.logs[0].args._newAddress, I_ModuleRegistryProxy.address); @@ -165,47 +161,48 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { ); // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : POLYMATH }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - // Step 9: Deploy the SecurityTokenRegistry + // Step 9: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: POLYMATH }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: POLYMATH}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, REGFEE, REGFEE, I_PolyToken.address, POLYMATH]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: POLYMATH}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 10: update the registries addresses from the PolymathRegistry contract + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + REGFEE, + REGFEE, + I_PolyToken.address, + POLYMATH + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); // 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}); + 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", + "FeatureRegistry contract was not deployed" ); // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_STRProxied.address, {from: POLYMATH}); - await I_MRProxied.updateFromRegistry({from: POLYMATH}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_STRProxied.address, { from: POLYMATH }); + await I_MRProxied.updateFromRegistry({ from: POLYMATH }); // STEP 6: Register the Modules with the ModuleRegistry contract // (A) : Register the GeneralTransferManagerFactory @@ -228,31 +225,31 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { // Step 13: Register tokens // (A) : TOK1 await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); - tx = await I_STRProxied.registerTicker(ISSUER1, symbol1, name1, { from : ISSUER1 }); + tx = await I_STRProxied.registerTicker(ISSUER1, symbol1, name1, { from: ISSUER1 }); assert.equal(tx.logs[0].args._owner, ISSUER1); assert.equal(tx.logs[0].args._ticker, symbol1); // (B) : TOK2 await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); - tx = await I_STRProxied.registerTicker(ISSUER2, symbol2, name2, { from : ISSUER2 }); + tx = await I_STRProxied.registerTicker(ISSUER2, symbol2, name2, { from: ISSUER2 }); assert.equal(tx.logs[0].args._owner, ISSUER2); assert.equal(tx.logs[0].args._ticker, symbol2); // (C) : TOK3 await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER3 }); - tx = await I_STRProxied.registerTicker(ISSUER3, symbol3, name3, { from : ISSUER3 }); + tx = await I_STRProxied.registerTicker(ISSUER3, symbol3, name3, { from: ISSUER3 }); assert.equal(tx.logs[0].args._owner, ISSUER3); assert.equal(tx.logs[0].args._ticker, symbol3); // Step 14: Deploy tokens // (A) : TOK1 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1}); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER1 }); let tx = await I_STRProxied.generateSecurityToken(name1, symbol1, tokenDetails1, false, { from: ISSUER1 }); assert.equal(tx.logs[1].args._ticker, symbol1, "SecurityToken doesn't get deployed"); I_SecurityToken1 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); // (B) : TOK2 - await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2}); + await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER2 }); tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails2, false, { from: ISSUER2 }); assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); I_SecurityToken2 = SecurityToken.at(tx.logs[1].args._securityTokenAddress); @@ -277,28 +274,33 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { `); }); - describe("USDTieredSTOFactory deploy", async() => { + describe("USDTieredSTOFactory deploy", async () => { // Step 1: Deploy Oracles // 1a - Deploy POLY Oracle - it("Should successfully deploy POLY Oracle and register on PolymathRegistry", async() => { - I_POLYOracle = await PolyOracle.new({ from: POLYMATH, value: web3.utils.toWei("1")}); + it("Should successfully deploy POLY Oracle and register on PolymathRegistry", async () => { + I_POLYOracle = await PolyOracle.new({ from: POLYMATH, value: web3.utils.toWei("1") }); console.log(I_POLYOracle.address); assert.notEqual( I_POLYOracle.address.valueOf(), "0x0000000000000000000000000000000000000000", - "POLYOracle contract was not deployed", + "POLYOracle contract was not deployed" ); tx = await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); assert.equal(tx.logs[0].args._nameKey, "PolyUsdOracle"); assert.equal(tx.logs[0].args._newAddress, I_POLYOracle.address); }); // 1b - Deploy ETH Oracle - it("Should successfully deploy ETH Oracle and register on PolymathRegistry", async() => { - I_USDOracle = await ETHOracle.new("0x216d678c14be600cb88338e763bb57755ca2b1cf", "0x0000000000000000000000000000000000000000", "ETH", { from: POLYMATH }); + it("Should successfully deploy ETH Oracle and register on PolymathRegistry", async () => { + I_USDOracle = await ETHOracle.new( + "0x216d678c14be600cb88338e763bb57755ca2b1cf", + "0x0000000000000000000000000000000000000000", + "ETH", + { from: POLYMATH } + ); assert.notEqual( I_USDOracle.address.valueOf(), "0x0000000000000000000000000000000000000000", - "USDOracle contract was not deployed", + "USDOracle contract was not deployed" ); tx = await I_PolymathRegistry.changeAddress("EthUsdOracle", I_USDOracle.address, { from: POLYMATH }); assert.equal(tx.logs[0].args._nameKey, "EthUsdOracle"); @@ -306,11 +308,18 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); }); - describe("USDTieredSTOFactory deploy", async() => { + describe("USDTieredSTOFactory deploy", async () => { // Step 1: Deploy USDTieredSTOFactory\ - it("Should successfully deploy USDTieredSTOFactory", async() => { + it("Should successfully deploy USDTieredSTOFactory", async () => { I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new(); - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: POLYMATH }); + I_USDTieredSTOFactory = await USDTieredSTOFactory.new( + I_PolyToken.address, + STOSetupCost, + 0, + 0, + I_USDTieredSTOProxyFactory.address, + { from: POLYMATH } + ); assert.notEqual( I_USDTieredSTOFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -320,7 +329,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { assert.equal(setupCost, STOSetupCost); }); // Step 2: Register and verify - it("Should successfully register and verify USDTieredSTOFactory contract", async() => { + it("Should successfully register and verify USDTieredSTOFactory contract", async () => { let tx = await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); assert.equal(tx.logs[0].args._moduleFactory, I_USDTieredSTOFactory.address); tx = await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); @@ -329,9 +338,9 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); }); - describe("CappedSTOFactory deploy", async() => { + describe("CappedSTOFactory deploy", async () => { // Step 1: Deploy new CappedSTOFactory - it("Should successfully deploy CappedSTOFactory", async() => { + it("Should successfully deploy CappedSTOFactory", async () => { I_UpgradedCappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); assert.notEqual( I_UpgradedCappedSTOFactory.address.valueOf(), @@ -343,7 +352,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); // Step 2: Register and verify - it("Should successfully register and verify new CappedSTOFactory contract", async() => { + it("Should successfully register and verify new CappedSTOFactory contract", async () => { let tx = await I_MRProxied.registerModule(I_UpgradedCappedSTOFactory.address, { from: POLYMATH }); assert.equal(tx.logs[0].args._moduleFactory, I_UpgradedCappedSTOFactory.address); tx = await I_MRProxied.verifyModule(I_UpgradedCappedSTOFactory.address, true, { from: POLYMATH }); @@ -352,17 +361,19 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); // Step 3: Unverify old CappedSTOFactory - it("Should successfully unverify old CappedSTOFactory contract", async() => { + it("Should successfully unverify old CappedSTOFactory contract", async () => { let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory.address, false, { from: POLYMATH }); assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory.address); assert.isFalse(tx.logs[0].args._verified); }); }); - describe("ManualApprovalTransferManagerFactory deploy", async() => { + describe("ManualApprovalTransferManagerFactory deploy", async () => { // Step 1: Deploy new ManualApprovalTransferManager - it("Should successfully deploy ManualApprovalTransferManagerFactory", async() => { - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); + it("Should successfully deploy ManualApprovalTransferManagerFactory", async () => { + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: POLYMATH + }); assert.notEqual( I_ManualApprovalTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -371,7 +382,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); // Step 2: Register and verify - it("Should successfully register and verify new ManualApprovalTransferManagerFactory contract", async() => { + it("Should successfully register and verify new ManualApprovalTransferManagerFactory contract", async () => { let tx = await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: POLYMATH }); assert.equal(tx.logs[0].args._moduleFactory, I_ManualApprovalTransferManagerFactory.address); tx = await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: POLYMATH }); @@ -380,7 +391,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); }); - describe("Change ownerships", async() => { + describe("Change ownerships", async () => { /* // Step 1: SecurityTokenRegistry it("Should successfully change ownership of new SecurityTokenRegistry contract", async() => { @@ -391,7 +402,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { */ // Step 2: Oracles - it("Should successfully change ownership of both Oracles contract", async() => { + it("Should successfully change ownership of both Oracles contract", async () => { let tx = await I_USDOracle.transferOwnership(MULTISIG, { from: POLYMATH }); assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous ETH Oracle owner was not Polymath account"); assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New ETH Oracle owner is not Multisig account"); @@ -402,96 +413,122 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { }); // Step 3: USDTieredSTOFactory - it("Should successfully change ownership of USDTieredSTOFactory contract", async() => { + it("Should successfully change ownership of USDTieredSTOFactory contract", async () => { let tx = await I_USDTieredSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous USDTieredSTOFactory owner was not Polymath account"); assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New USDTieredSTOFactory owner is not Multisig account"); }); // Step 3: CappedSTOFactory - it("Should successfully change ownership of CappedSTOFactory contract", async() => { + it("Should successfully change ownership of CappedSTOFactory contract", async () => { let tx = await I_UpgradedCappedSTOFactory.transferOwnership(MULTISIG, { from: POLYMATH }); assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous USDTieredSTOFactory owner was not Polymath account"); assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New USDTieredSTOFactory owner is not Multisig account"); }); // Step 4: ManualApprovalTransferManagerFactory - it("Should successfully change ownership of ManualApprovalTransferManagerFactory contract", async() => { + it("Should successfully change ownership of ManualApprovalTransferManagerFactory contract", async () => { let tx = await I_ManualApprovalTransferManagerFactory.transferOwnership(MULTISIG, { from: POLYMATH }); - assert.equal(tx.logs[0].args.previousOwner, POLYMATH, "Previous ManualApprovalTransferManagerFactory owner was not Polymath account"); + assert.equal( + tx.logs[0].args.previousOwner, + POLYMATH, + "Previous ManualApprovalTransferManagerFactory owner was not Polymath account" + ); assert.equal(tx.logs[0].args.newOwner, MULTISIG, "New ManualApprovalTransferManagerFactory owner is not Multisig account"); }); }); - describe("Polymath network status post migration", async() => { + describe("Polymath network status post migration", async () => { // Launch STO for TOK1 - it("Should successfully launch USDTieredSTO for first security token", async() => { + it("Should successfully launch USDTieredSTO for first security token", async () => { let _startTime = latestTime() + duration.days(1); let _endTime = _startTime + duration.days(180); - let _ratePerTier = [BigNumber(0.1).mul(10**18), BigNumber(0.15).mul(10**18), BigNumber(0.2).mul(10**18)]; + let _ratePerTier = [BigNumber(0.1).mul(10 ** 18), BigNumber(0.15).mul(10 ** 18), BigNumber(0.2).mul(10 ** 18)]; let _ratePerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; - let _tokensPerTierTotal = [BigNumber(100).mul(10**18), BigNumber(200).mul(10**18), BigNumber(300).mul(10**18)]; + let _tokensPerTierTotal = [BigNumber(100).mul(10 ** 18), BigNumber(200).mul(10 ** 18), BigNumber(300).mul(10 ** 18)]; let _tokensPerTierDiscountPoly = [BigNumber(0), BigNumber(0), BigNumber(0)]; - let _nonAccreditedLimitUSD = BigNumber(100).mul(10**18); - let _minimumInvestmentUSD = BigNumber(5).mul(10**18); + let _nonAccreditedLimitUSD = BigNumber(100).mul(10 ** 18); + let _minimumInvestmentUSD = BigNumber(5).mul(10 ** 18); let _fundRaiseTypes = [0, 1]; let _wallet = ISSUER1; let _reserveWallet = ISSUER1; let _usdToken = I_DaiToken.address; let config = [ - _startTime, _endTime, _ratePerTier, _ratePerTierDiscountPoly, _tokensPerTierTotal, - _tokensPerTierDiscountPoly, _nonAccreditedLimitUSD, _minimumInvestmentUSD, - _fundRaiseTypes, _wallet, _reserveWallet, _usdToken + _startTime, + _endTime, + _ratePerTier, + _ratePerTierDiscountPoly, + _tokensPerTierTotal, + _tokensPerTierDiscountPoly, + _nonAccreditedLimitUSD, + _minimumInvestmentUSD, + _fundRaiseTypes, + _wallet, + _reserveWallet, + _usdToken ]; let functionSignature = { - name: 'configure', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_startTime' - },{ - type: 'uint256', - name: '_endTime' - },{ - type: 'uint256[]', - name: '_ratePerTier' - },{ - type: 'uint256[]', - name: '_ratePerTierDiscountPoly' - },{ - type: 'uint256[]', - name: '_tokensPerTier' - },{ - type: 'uint256[]', - name: '_tokensPerTierDiscountPoly' - },{ - type: 'uint256', - name: '_nonAccreditedLimitUSD' - },{ - type: 'uint256', - name: '_minimumInvestmentUSD' - },{ - type: 'uint8[]', - name: '_fundRaiseTypes' - },{ - type: 'address', - name: '_wallet' - },{ - type: 'address', - name: '_reserveWallet' - },{ - type: 'address', - name: '_usdToken' - }] + name: "configure", + type: "function", + inputs: [ + { + type: "uint256", + name: "_startTime" + }, + { + type: "uint256", + name: "_endTime" + }, + { + type: "uint256[]", + name: "_ratePerTier" + }, + { + type: "uint256[]", + name: "_ratePerTierDiscountPoly" + }, + { + type: "uint256[]", + name: "_tokensPerTier" + }, + { + type: "uint256[]", + name: "_tokensPerTierDiscountPoly" + }, + { + type: "uint256", + name: "_nonAccreditedLimitUSD" + }, + { + type: "uint256", + name: "_minimumInvestmentUSD" + }, + { + type: "uint8[]", + name: "_fundRaiseTypes" + }, + { + type: "address", + name: "_wallet" + }, + { + type: "address", + name: "_reserveWallet" + }, + { + type: "address", + name: "_usdToken" + } + ] }; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); let tx = await I_SecurityToken1.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER1 }); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"USDTieredSTO","USDTieredSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); I_USDTieredSTO = USDTieredSTO.at(tx.logs[2].args._module); }); @@ -506,7 +543,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { */ // Launch NewCappedSTO for TOK2 - it("Should successfully launch CappedSTO for third security token", async() => { + it("Should successfully launch CappedSTO for third security token", async () => { let startTime = latestTime() + duration.days(1); let endTime = startTime + duration.days(30); let cap = web3.utils.toWei("500000"); @@ -518,14 +555,18 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { let tx = await I_SecurityToken2.addModule(I_UpgradedCappedSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER2 }); assert.equal(tx.logs[2].args._types[0], STOKEY, "CappedSTO doesn't get deployed"); - assert.equal(web3.utils.hexToString(tx.logs[2].args._name),"CappedSTO","CappedSTOFactory module was not added"); + assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "CappedSTO", "CappedSTOFactory module was not added"); }); // Attach ManualApprovalTransferManager module for TOK2 it("Should successfully attach the ManualApprovalTransferManagerFactory with the second token", async () => { const tx = await I_SecurityToken2.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, { from: ISSUER2 }); assert.equal(tx.logs[2].args._types[0].toNumber(), TMKEY, "ManualApprovalTransferManagerFactory doesn't get deployed"); - assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManagerFactory module was not added"); + assert.equal( + web3.utils.toUtf8(tx.logs[2].args._name), + "ManualApprovalTransferManager", + "ManualApprovalTransferManagerFactory module was not added" + ); I_ManualApprovalTransferManagerFactory = ManualApprovalTransferManagerFactory.at(tx.logs[2].args._module); }); }); diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 5569d35b6..d46d6f1f7 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -1,27 +1,25 @@ -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { encodeProxyCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { encodeProxyCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); -const OwnedUpgradeabilityProxy = artifacts.require('./OwnedUpgradeabilityProxy.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol') -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol') -const STFactory = artifacts.require('./STFactory.sol'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol') - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract ("SecurityTokenRegistryProxy", accounts => { - - +const OwnedUpgradeabilityProxy = artifacts.require("./OwnedUpgradeabilityProxy.sol"); +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const STFactory = artifacts.require("./STFactory.sol"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("SecurityTokenRegistryProxy", accounts => { let I_SecurityTokenRegistry; let I_SecurityTokenRegistryProxy; let I_GeneralTransferManagerFactory; @@ -53,14 +51,14 @@ contract ("SecurityTokenRegistryProxy", accounts => { const decimals = 18; const transferManagerKey = 2; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; async function readStorage(contractAddress, slot) { return await web3.eth.getStorageAt(contractAddress, slot); } - before(async() => { + before(async () => { account_polymath = accounts[0]; account_temp = accounts[1]; token_owner = accounts[2]; @@ -69,32 +67,30 @@ contract ("SecurityTokenRegistryProxy", accounts => { // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -104,41 +100,35 @@ contract ("SecurityTokenRegistryProxy", accounts => { // Register the Modules with the ModuleRegistry contract - // Step 3: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // (A) : Register the GeneralTransferManagerFactory await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -150,41 +140,60 @@ contract ("SecurityTokenRegistryProxy", accounts => { `); }); - describe("Attach the implementation address", async() => { - + describe("Attach the implementation address", async () => { // Storage // __version -- index 11 // __implementation -- index 12 // __upgradeabilityOwner -- index 13 - it("Should attach the implementation and version", async() => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + it("Should attach the implementation and version", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.0.0"); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, "") + .replace(/\n/, ""), + "1.0.0" + ); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); }); - it("Verify the initialize data", async() => { - assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))).toNumber(), 60*24*60*60, "Should equal to 60 days"); - assert.equal((await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("tickerRegFee"))).toNumber(), web3.utils.toWei("250")); + it("Verify the initialize data", async () => { + assert.equal( + (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("expiryLimit"))).toNumber(), + 60 * 24 * 60 * 60, + "Should equal to 60 days" + ); + assert.equal( + (await I_STRProxied.getUintValues.call(web3.utils.soliditySha3("tickerRegFee"))).toNumber(), + web3.utils.toWei("250") + ); }); + }); - }) - - describe("Feed some data in storage", async() => { - - it("Register the ticker", async() => { + describe("Feed some data in storage", async () => { + it("Register the ticker", async () => { await I_PolyToken.getTokens(web3.utils.toWei("1000"), token_owner); - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from : token_owner }); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, name, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner, "Owner should be the same as registered with the ticker"); assert.equal(tx.logs[0].args._ticker, symbol, "Same as the symbol registered in the registerTicker function call"); }); it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner}); + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); @@ -193,60 +202,62 @@ contract ("SecurityTokenRegistryProxy", accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); - assert.equal(web3.utils.hexToString(log.args._name),"GeneralTransferManager"); + assert.equal(web3.utils.hexToString(log.args._name), "GeneralTransferManager"); }); - }) - - describe("Upgrade the imlplementation address", async() => { + }); - it("Should upgrade the version and implementation address -- fail bad owner", async() => { - - I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({from: account_polymath}); - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_temp})); + describe("Upgrade the imlplementation address", async () => { + it("Should upgrade the version and implementation address -- fail bad owner", async () => { + I_SecurityTokenRegistryMock = await SecurityTokenRegistryMock.new({ from: account_polymath }); + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, { from: account_temp })); }); - it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); + it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async () => { + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", account_temp, { from: account_polymath })); }); - it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); + it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async () => { + await catchRevert( + I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", { from: account_polymath }) + ); }); - it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistry.address, {from: account_polymath})); + it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async () => { + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistry.address, { from: account_polymath })); }); - it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("1.0.0", I_SecurityTokenRegistryMock.address, {from: account_polymath})); + it("Should upgrade the version and implementation address -- same version as previous is not allowed", async () => { + await catchRevert( + I_SecurityTokenRegistryProxy.upgradeTo("1.0.0", I_SecurityTokenRegistryMock.address, { from: account_polymath }) + ); }); - it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { - - await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("", I_SecurityTokenRegistryMock.address, {from: account_polymath})); + it("Should upgrade the version and implementation address -- empty version string is not allowed", async () => { + await catchRevert(I_SecurityTokenRegistryProxy.upgradeTo("", I_SecurityTokenRegistryMock.address, { from: account_polymath })); }); - it("Should upgrade the version and the implementation address successfully", async() => { - await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, {from: account_polymath}); + it("Should upgrade the version and the implementation address successfully", async () => { + await I_SecurityTokenRegistryProxy.upgradeTo("1.1.0", I_SecurityTokenRegistryMock.address, { from: account_polymath }); let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.1.0", "Version mis-match"); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, "") + .replace(/\n/, ""), + "1.1.0", + "Version mis-match" + ); assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistryMock.address, "Implemnted address is not matched"); I_STRProxied = await SecurityTokenRegistryMock.at(I_SecurityTokenRegistryProxy.address); }); }); - describe("Execute functionality of the implementation contract on the earlier storage", async() => { - - it("Should get the previous data", async() => { + describe("Execute functionality of the implementation contract on the earlier storage", async () => { + it("Should get the previous data", async () => { let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); let _data = await I_STRProxied.getSecurityTokenData.call(_tokenAddress); assert.equal(_data[0], symbol, "Symbol should match with registered symbol"); @@ -254,40 +265,44 @@ contract ("SecurityTokenRegistryProxy", accounts => { assert.equal(_data[2], tokenDetails, "Token details should matched with deployed ticker"); }); - it("Should alter the old storage", async() => { - await I_STRProxied.changeTheDeployedAddress(symbol, account_temp, {from: account_polymath}); + it("Should alter the old storage", async () => { + await I_STRProxied.changeTheDeployedAddress(symbol, account_temp, { from: account_polymath }); let _tokenAddress = await I_STRProxied.getSecurityTokenAddress.call(symbol); assert.equal(_tokenAddress, account_temp, "Should match with the changed address"); }); - }) - - describe("Transfer the ownership of the proxy contract", async() => { + }); - it("Should change the ownership of the contract -- because of bad owner", async()=> { - - await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); + describe("Transfer the ownership of the proxy contract", async () => { + it("Should change the ownership of the contract -- because of bad owner", async () => { + await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_temp })); }); - it("Should change the ownership of the contract -- new address should not be 0x", async()=> { - - await catchRevert(I_SecurityTokenRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); + it("Should change the ownership of the contract -- new address should not be 0x", async () => { + await catchRevert( + I_SecurityTokenRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", { from: account_polymath }) + ); }); - it("Should change the ownership of the contract", async()=> { - await I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_polymath}); - let _currentOwner = await I_SecurityTokenRegistryProxy.proxyOwner.call({from: account_polymath_new}); + it("Should change the ownership of the contract", async () => { + await I_SecurityTokenRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_polymath }); + let _currentOwner = await I_SecurityTokenRegistryProxy.proxyOwner.call({ from: account_polymath_new }); assert.equal(_currentOwner, account_polymath_new, "Should equal to the new owner"); }); - it("Should change the implementation contract and version by the new owner", async() => { - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath}); - await I_SecurityTokenRegistryProxy.upgradeTo("1.2.0", I_SecurityTokenRegistry.address, {from: account_polymath_new}); + it("Should change the implementation contract and version by the new owner", async () => { + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); + await I_SecurityTokenRegistryProxy.upgradeTo("1.2.0", I_SecurityTokenRegistry.address, { from: account_polymath_new }); let c = OwnedUpgradeabilityProxy.at(I_SecurityTokenRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.2.0", "Version mis-match"); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, "") + .replace(/\n/, ""), + "1.2.0", + "Version mis-match" + ); assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address, "Implemnted address is not matched"); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); }); - }) - - -}) + }); +}); diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index 67e6a57a0..7c8cf3a71 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -1,28 +1,26 @@ -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import { encodeProxyCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { encodeProxyCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); -const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); +const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const MockModuleRegistry = artifacts.require("./MockModuleRegistry.sol"); -const OwnedUpgradeabilityProxy = artifacts.require('./OwnedUpgradeabilityProxy.sol'); -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol') -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol') -const STFactory = artifacts.require('./STFactory.sol'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const FeatureRegistry = artifacts.require('./FeatureRegistry.sol') - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract ("ModuleRegistryProxy", accounts => { - - +const OwnedUpgradeabilityProxy = artifacts.require("./OwnedUpgradeabilityProxy.sol"); +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const STFactory = artifacts.require("./STFactory.sol"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("ModuleRegistryProxy", accounts => { let I_SecurityTokenRegistry; let I_SecurityTokenRegistryProxy; let I_GeneralTransferManagerFactory; @@ -55,14 +53,14 @@ contract ("ModuleRegistryProxy", accounts => { const decimals = 18; const transferManagerKey = 2; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; async function readStorage(contractAddress, slot) { return await web3.eth.getStorageAt(contractAddress, slot); } - before(async() => { + before(async () => { account_polymath = accounts[0]; account_temp = accounts[1]; token_owner = accounts[2]; @@ -71,49 +69,47 @@ contract ("ModuleRegistryProxy", accounts => { // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", + "SecurityTokenRegistry contract was not deployed" ); - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // Printing all the contract addresses - console.log(` + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); + + // Printing all the contract addresses + console.log(` --------------------- Polymath Network Smart Contracts: --------------------- PolymathRegistry: ${PolymathRegistry.address} SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} @@ -126,26 +122,33 @@ contract ("ModuleRegistryProxy", accounts => { `); }); - describe("Attach the implementation address", async() => { - + describe("Attach the implementation address", async () => { // Storage // __version -- index 11 // __implementation -- index 12 // __upgradeabilityOwner -- index 13 - it("Should attach the MR implementation and version", async() => { + it("Should attach the MR implementation and version", async () => { let bytesProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, {from: account_polymath}); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, { from: account_polymath }); let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.0.0"); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, "") + .replace(/\n/, ""), + "1.0.0" + ); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); }); - it("Deploy the essential smart contracts", async() => { + it("Deploy the essential smart contracts", async () => { // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -159,29 +162,31 @@ contract ("ModuleRegistryProxy", accounts => { await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // Step 3: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); assert.notEqual( I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", + "STFactory contract was not deployed" ); - }) - - it("Verify the initialize data", async() => { - assert.equal((await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("owner"))), account_polymath, "Should equal to right address"); - assert.equal((await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry"))), I_PolymathRegistry.address); }); - }) - - describe("Feed some data in storage", async() => { - - it("Register and verify the new module", async() => { + it("Verify the initialize data", async () => { + assert.equal( + await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("owner")), + account_polymath, + "Should equal to right address" + ); + assert.equal(await I_MRProxied.getAddressValues.call(web3.utils.soliditySha3("polymathRegistry")), I_PolymathRegistry.address); + }); + }); - I_GeneralPermissionManagerfactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + describe("Feed some data in storage", async () => { + it("Register and verify the new module", async () => { + I_GeneralPermissionManagerfactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerfactory.address.valueOf(), @@ -191,94 +196,99 @@ contract ("ModuleRegistryProxy", accounts => { await I_MRProxied.registerModule(I_GeneralPermissionManagerfactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralPermissionManagerfactory.address, true, { from: account_polymath }); - }); + }); - }) - - describe("Upgrade the imlplementation address", async() => { - - it("Should upgrade the version and implementation address -- fail bad owner", async() => { - - I_MockModuleRegistry = await MockModuleRegistry.new({from: account_polymath}); - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_temp})); + describe("Upgrade the imlplementation address", async () => { + it("Should upgrade the version and implementation address -- fail bad owner", async () => { + I_MockModuleRegistry = await MockModuleRegistry.new({ from: account_polymath }); + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, { from: account_temp })); }); - it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", account_temp, {from: account_polymath})); + it("Should upgrade the version and implementation address -- Implementaion address should be a contract address", async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", account_temp, { from: account_polymath })); }); - it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", {from: account_polymath})); + it("Should upgrade the version and implementation address -- Implemenation address should not be 0x", async () => { + await catchRevert( + I_ModuleRegistryProxy.upgradeTo("1.1.0", "0x00000000000000000000000000000000000000", { from: account_polymath }) + ); }); - it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_ModuleRegistry.address, {from: account_polymath})); + it("Should upgrade the version and implementation address -- Implemenation address should not be the same address", async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.1.0", I_ModuleRegistry.address, { from: account_polymath })); }); - it("Should upgrade the version and implementation address -- same version as previous is not allowed", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.0.0", I_MockModuleRegistry.address, {from: account_polymath})); + it("Should upgrade the version and implementation address -- same version as previous is not allowed", async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo("1.0.0", I_MockModuleRegistry.address, { from: account_polymath })); }); - it("Should upgrade the version and implementation address -- empty version string is not allowed", async() => { - - await catchRevert(I_ModuleRegistryProxy.upgradeTo("", I_MockModuleRegistry.address, {from: account_polymath})); + it("Should upgrade the version and implementation address -- empty version string is not allowed", async () => { + await catchRevert(I_ModuleRegistryProxy.upgradeTo("", I_MockModuleRegistry.address, { from: account_polymath })); }); - it("Should upgrade the version and the implementation address successfully", async() => { - await I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, {from: account_polymath}); + it("Should upgrade the version and the implementation address successfully", async () => { + await I_ModuleRegistryProxy.upgradeTo("1.1.0", I_MockModuleRegistry.address, { from: account_polymath }); let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.1.0", "Version mis-match"); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, "") + .replace(/\n/, ""), + "1.1.0", + "Version mis-match" + ); assert.equal(await readStorage(c.address, 12), I_MockModuleRegistry.address, "Implemnted address is not matched"); I_MRProxied = await MockModuleRegistry.at(I_ModuleRegistryProxy.address); }); }); - describe("Execute functionality of the implementation contract on the earlier storage", async() => { - - it("Should get the previous data", async() => { + describe("Execute functionality of the implementation contract on the earlier storage", async () => { + it("Should get the previous data", async () => { let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); assert.equal(_data.length, 0, "Should give the original length"); }); - it("Should alter the old storage", async() => { - await I_MRProxied.addMoreReputation(I_GeneralTransferManagerFactory.address, [account_polymath, account_temp], {from: account_polymath}); + it("Should alter the old storage", async () => { + await I_MRProxied.addMoreReputation(I_GeneralTransferManagerFactory.address, [account_polymath, account_temp], { + from: account_polymath + }); let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); assert.equal(_data.length, 2, "Should give the updated length"); }); - }) - - describe("Transfer the ownership of the proxy contract", async() => { + }); - it("Should change the ownership of the contract -- because of bad owner", async()=> { - - await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_temp})); + describe("Transfer the ownership of the proxy contract", async () => { + it("Should change the ownership of the contract -- because of bad owner", async () => { + await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_temp })); }); - it("Should change the ownership of the contract -- new address should not be 0x", async()=> { - - await catchRevert(I_ModuleRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", {from: account_polymath})); + it("Should change the ownership of the contract -- new address should not be 0x", async () => { + await catchRevert( + I_ModuleRegistryProxy.transferProxyOwnership("0x00000000000000000000000000000000000000", { from: account_polymath }) + ); }); - it("Should change the ownership of the contract", async()=> { - await I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, {from: account_polymath}); - let _currentOwner = await I_ModuleRegistryProxy.proxyOwner.call({from: account_polymath_new}); + it("Should change the ownership of the contract", async () => { + await I_ModuleRegistryProxy.transferProxyOwnership(account_polymath_new, { from: account_polymath }); + let _currentOwner = await I_ModuleRegistryProxy.proxyOwner.call({ from: account_polymath_new }); assert.equal(_currentOwner, account_polymath_new, "Should equal to the new owner"); }); - it("Should change the implementation contract and version by the new owner", async() => { - I_ModuleRegistry = await ModuleRegistry.new({from: account_polymath}); - await I_ModuleRegistryProxy.upgradeTo("1.2.0", I_ModuleRegistry.address, {from: account_polymath_new}); + it("Should change the implementation contract and version by the new owner", async () => { + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); + await I_ModuleRegistryProxy.upgradeTo("1.2.0", I_ModuleRegistry.address, { from: account_polymath_new }); let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); - assert.equal((web3.utils.toAscii(await readStorage(c.address, 11)).replace(/\u0000/g, '')).replace(/\n/, ''), "1.2.0", "Version mis-match"); + assert.equal( + web3.utils + .toAscii(await readStorage(c.address, 11)) + .replace(/\u0000/g, "") + .replace(/\n/, ""), + "1.2.0", + "Version mis-match" + ); assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address, "Implemnted address is not matched"); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); }); - }) - - -}) + }); +}); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index a5b69b6c6..9a2154c7b 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -1,31 +1,30 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall } from './helpers/encodeCall'; -import { catchRevert } from './helpers/exceptions'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const TrackedRedemptionFactory = artifacts.require('./TrackedRedemptionFactory.sol'); -const TrackedRedemption = artifacts.require('./TrackedRedemption'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('TrackedRedemption', accounts => { - +import latestTime from "./helpers/latestTime"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; + +const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); +const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const TrackedRedemptionFactory = artifacts.require("./TrackedRedemptionFactory.sol"); +const TrackedRedemption = artifacts.require("./TrackedRedemption"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("TrackedRedemption", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -79,10 +78,10 @@ contract('TrackedRedemption', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const MRProxyParameters = ["address", "address"]; - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -95,35 +94,33 @@ contract('TrackedRedemption', accounts => { account_investor4 = accounts[9]; account_temp = accounts[2]; - // ----------- POLYMATH NETWORK Configuration ------------ + // ----------- POLYMATH NETWORK Configuration ------------ // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); // Step 1: Deploy the token Faucet and Mint tokens for token_owner I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - // Step 2: Deploy the FeatureRegistry + // Step 2: Deploy the FeatureRegistry - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); + I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { + from: account_polymath + }); // STEP 3: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); // STEP 4: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), @@ -133,7 +130,9 @@ contract('TrackedRedemption', accounts => { // STEP 5: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -142,60 +141,64 @@ contract('TrackedRedemption', accounts => { ); // STEP 4: Deploy the TrackedRedemption - I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); assert.notEqual( I_TrackedRedemptionFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "TrackedRedemptionFactory contract was not deployed" ); + // Step 6: Deploy the STFactory contract - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); + assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - // Step 7: Deploy the SecurityTokenRegistry contract + // Step 7: Deploy the SecurityTokenRegistry contract - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed" + ); - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + I_PolymathRegistry.address, + I_STFactory.address, + initRegFee, + initRegFee, + I_PolyToken.address, + account_polymath + ]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); + await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // STEP 5: Register the Modules with the ModuleRegistry contract + // STEP 5: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the TrackedRedemptionFactory - await I_MRProxied.registerModule(I_TrackedRedemptionFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_TrackedRedemptionFactory.address, true, { from: account_polymath }); + // (C) : Register the TrackedRedemptionFactory + await I_MRProxied.registerModule(I_TrackedRedemptionFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_TrackedRedemptionFactory.address, true, { from: account_polymath }); // Printing all the contract addresses console.log(` @@ -216,11 +219,10 @@ contract('TrackedRedemption', accounts => { `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -235,29 +237,23 @@ contract('TrackedRedemption', accounts => { I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the TrackedRedemption with the security token", async () => { const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, "", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "TrackedRedemption", "TrackedRedemption module was not added" ); @@ -265,9 +261,8 @@ contract('TrackedRedemption', accounts => { }); }); - describe("Make Redemptions", async() => { - - it("Buy some tokens for account_investor1 (1 ETH)", async() => { + describe("Make Redemptions", async () => { + it("Buy some tokens for account_investor1 (1 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -279,23 +274,25 @@ contract('TrackedRedemption', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor1.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Jump time await increaseTime(5000); // Mint some tokens - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), - web3.utils.toWei('1', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("1", "ether")); }); - it("Buy some tokens for account_investor2 (2 ETH)", async() => { + it("Buy some tokens for account_investor2 (2 ETH)", async () => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( @@ -307,68 +304,65 @@ contract('TrackedRedemption', accounts => { { from: account_issuer, gas: 500000 - }); + } + ); - assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor2.toLowerCase(), + "Failed in adding the investor in whitelist" + ); // Mint some tokens - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei("2", "ether"), { from: token_owner }); - assert.equal( - (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), - web3.utils.toWei('2', 'ether') - ); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("2", "ether")); }); - it("Redeem some tokens - fail insufficient allowance", async() => { - await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, {from : token_owner}); + it("Redeem some tokens - fail insufficient allowance", async () => { + await I_GeneralTransferManager.changeAllowAllBurnTransfers(true, { from: token_owner }); - - await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1})); + await catchRevert(I_TrackedRedemption.redeemTokens(web3.utils.toWei("1", "ether"), { from: account_investor1 })); }); - it("Redeem some tokens", async() => { - await I_SecurityToken.approve(I_TrackedRedemption.address, web3.utils.toWei('1', 'ether'), {from: account_investor1}); - let tx = await I_TrackedRedemption.redeemTokens(web3.utils.toWei('1', 'ether'), {from: account_investor1}); + it("Redeem some tokens", async () => { + await I_SecurityToken.approve(I_TrackedRedemption.address, web3.utils.toWei("1", "ether"), { from: account_investor1 }); + let tx = await I_TrackedRedemption.redeemTokens(web3.utils.toWei("1", "ether"), { from: account_investor1 }); console.log(JSON.stringify(tx.logs)); assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Mismatch address"); - assert.equal(tx.logs[0].args._value, web3.utils.toWei('1', 'ether'), "Wrong value"); + assert.equal(tx.logs[0].args._value, web3.utils.toWei("1", "ether"), "Wrong value"); }); - it("Get the init data", async() => { + it("Get the init data", async () => { let tx = await I_TrackedRedemption.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ""), 0); }); - it("Should get the listed permissions", async() => { + it("Should get the listed permissions", async () => { let tx = await I_TrackedRedemption.getPermissions.call(); - assert.equal(tx.length,0); + assert.equal(tx.length, 0); }); - describe("Test cases for the TrackedRedemptionFactory", async() => { - it("should get the exact details of the factory", async() => { + describe("Test cases for the TrackedRedemptionFactory", async () => { + it("should get the exact details of the factory", async () => { assert.equal((await I_TrackedRedemptionFactory.setupCost.call()).toNumber(), 0); assert.equal((await I_TrackedRedemptionFactory.getTypes.call())[0], 5); assert.equal(await I_TrackedRedemptionFactory.getVersion.call(), "1.0.0"); - assert.equal(web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()) - .replace(/\u0000/g, ''), - "TrackedRedemption", - "Wrong Module added"); - assert.equal(await I_TrackedRedemptionFactory.getDescription.call(), - "Track token redemptions", - "Wrong Module added"); - assert.equal(await I_TrackedRedemptionFactory.getTitle.call(), - "Tracked Redemption", - "Wrong Module added"); - assert.equal(await I_TrackedRedemptionFactory.getInstructions.call(), - "Allows an investor to redeem security tokens which are tracked by this module", - "Wrong Module added"); + assert.equal( + web3.utils.toAscii(await I_TrackedRedemptionFactory.getName.call()).replace(/\u0000/g, ""), + "TrackedRedemption", + "Wrong Module added" + ); + assert.equal(await I_TrackedRedemptionFactory.getDescription.call(), "Track token redemptions", "Wrong Module added"); + assert.equal(await I_TrackedRedemptionFactory.getTitle.call(), "Tracked Redemption", "Wrong Module added"); + assert.equal( + await I_TrackedRedemptionFactory.getInstructions.call(), + "Allows an investor to redeem security tokens which are tracked by this module", + "Wrong Module added" + ); let tags = await I_TrackedRedemptionFactory.getTags.call(); assert.equal(tags.length, 2); - }); }); - }); - }); From 618c260f9192789d008c01d8deaf8777b133769d Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 11:13:22 +0530 Subject: [PATCH 063/142] general transfer manager test fix --- test/h_general_transfer_manager.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index a54976c8c..0c79b4348 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -586,6 +586,25 @@ contract("GeneralTransferManager", accounts => { await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: account_delegate })); }); + it("Factory owner should pull fees", async() => { + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FEE_ADMIN", true, {from: token_owner}); + let balanceBefore = await I_PolyToken.balanceOf(account_polymath); + await I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate}); + let balanceAfter = await I_PolyToken.balanceOf(account_polymath); + assert.equal(balanceBefore.add(web3.utils.toWei('1','ether')).toNumber(), balanceAfter.toNumber(), "Fee is transferred"); + }); + + it("Should change the white list transfer variable", async() => { + let tx = await I_GeneralTransferManager.changeAllowAllWhitelistIssuances(true, {from : token_owner}); + assert.isTrue(tx.logs[0].args._allowAllWhitelistIssuances); + }); + + it("should failed in trasfering the tokens", async() => { + let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); + await I_GeneralTransferManager.pause({from: token_owner}); + await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2','ether'), {from: account_investor2})); + }); + it("Should change the Issuance address", async () => { let tx = await I_GeneralTransferManager.changeIssuanceAddress(account_investor2, { from: account_delegate }); assert.equal(tx.logs[0].args._issuanceAddress, account_investor2); From 77e91de9a2b9ec37914d92876a4611b6986ddee4 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 11:13:43 +0530 Subject: [PATCH 064/142] Ignore helpers and oracles in coverage --- .solcover.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.solcover.js b/.solcover.js index 17939eeff..5f1828c6b 100644 --- a/.solcover.js +++ b/.solcover.js @@ -4,5 +4,5 @@ module.exports = { copyPackages: ['openzeppelin-solidity'], testCommand: 'node ../node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` --network coverage', deepSkip: true, - skipFiles: ['external', 'flat', 'mocks'] + skipFiles: ['external', 'flat', 'mocks', 'helpers', 'oracles'] }; From b20c4155849b8d6a7864d2037648df6228eb6af3 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 11:19:06 +0530 Subject: [PATCH 065/142] usd tiered sto test fix --- test/p_usd_tiered_sto.js | 941 ++++++++++++++++++++++++++++++++++- test/q_usd_tiered_sto_sim.js | 18 +- 2 files changed, 940 insertions(+), 19 deletions(-) diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index cd4d97df4..9caee056d 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -978,11 +978,11 @@ contract("USDTieredSTO", accounts => { }); describe("Test buying failure conditions", async () => { - it("should fail if before STO start time", async () => { + it("should fail if before STO start time", async() => { let stoId = 0; let snapId = await takeSnapshot(); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, "STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); // Whitelist let fromTime = latestTime(); @@ -990,8 +990,8 @@ contract("USDTieredSTO", accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); // // Advance time to after STO start // await increaseTime(duration.days(3)); @@ -1000,27 +1000,938 @@ contract("USDTieredSTO", accounts => { await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); // Prep for investments - let investment_ETH = web3.utils.toWei("1", "ether"); // Invest 1 ETH - let investment_POLY = web3.utils.toWei("10000", "ether"); // Invest 10000 POLY + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - let investment_DAI = web3.utils.toWei("500", "ether"); // Invest 10000 POLY + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); // NONACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); + + // NONACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + + // NONACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); + + // ACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); + + // ACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + + // ACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + + await revertToSnapshot(snapId); + }); + + it("should fail if not whitelisted", async() => { + let stoId = 0; + let snapId = await takeSnapshot(); + + // // Whitelist + // let fromTime = latestTime(); + // let toTime = latestTime() + duration.days(15); + // let expiryTime = toTime + duration.days(100); + // let whitelisted = true; + // + // await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + // await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + + // Advance time to after STO start + await increaseTime(duration.days(3)); + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + // Prep for investments + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + + // NONACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); - // Buy with POLY NONACCREDITED + // NONACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); - await catchRevert( - I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) - ); + // NONACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); + + // ACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); + + // ACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + + // ACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + + await revertToSnapshot(snapId); + }); + + it("should fail if minimumInvestmentUSD not met", async() => { + let stoId = 0; + let tierId = 0; + let snapId = await takeSnapshot(); + + // Whitelist + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + + // Advance time to after STO start + await increaseTime(duration.days(3)); + + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + let investment_USD = BigNumber(2).mul(10**18); + let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); + let investment_POLY = await convert(stoId, tierId, false, "USD", "POLY", investment_USD); + let investment_DAI = investment_USD; + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + + // NONACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); + + // NONACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + + // NONACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); + + // ACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); + + // ACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + + // ACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + + await revertToSnapshot(snapId); + }); + + it("should successfully pause the STO and make investments fail, then unpause and succeed", async() => { + let stoId = 0; + let snapId = await takeSnapshot(); + + // Whitelist + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + + // Advance time to after STO start + await increaseTime(duration.days(3)); + + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + // Pause the STO + await I_USDTieredSTO_Array[stoId].pause({ from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), true, 'STO did not pause successfully'); + + // Prep for investments + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + + // NONACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); + + // NONACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + + // NONACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); + + // ACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); + + // ACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + + // ACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + + // Unpause the STO + await I_USDTieredSTO_Array[stoId].unpause({ from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), false, 'STO did not unpause successfully'); + + await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); + await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); + await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); + + await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); + await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); + await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); + + await revertToSnapshot(snapId); + }); + + it("should fail if after STO end time", async() => { + let stoId = 3; + let snapId = await takeSnapshot(); + + // Whitelist + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + + // Advance time to after STO end + await increaseTime(duration.days(3)); + + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + // Prep for investments + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + + + // NONACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); + + // NONACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + + // NONACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); + + // ACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); + + // ACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + + // ACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + + await revertToSnapshot(snapId); + }); + + it("should fail if finalized", async() => { + let stoId = 0; + let snapId = await takeSnapshot(); + + // Whitelist + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(RESERVEWALLET, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + + // Advance time to after STO start + await increaseTime(duration.days(3)); + + // Set as accredited + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + // Finalize STO + await I_USDTieredSTO_Array[stoId].finalize({ from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[stoId].isFinalized.call(), true, "STO has not been finalized"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + + // Attempt to call function again + await catchRevert(I_USDTieredSTO_Array[stoId].finalize({ from: ISSUER })); + + // Prep for investments + let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH + let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + + // NONACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); + + // NONACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + + // NONACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); + + // ACCREDITED ETH + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); + + // ACCREDITED POLY + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + + // ACCREDITED DAI + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + + await revertToSnapshot(snapId); + }); + }); + + describe("Prep STO", async() => { + + it("should jump forward to after STO start", async() => { + let stoId = 0; + await increaseTime(duration.days(3)); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),true,"STO is not showing correct status"); + }); + + it("should whitelist ACCREDITED1 and NONACCREDITED1", async() => { + let stoId = 0; + + let fromTime = latestTime(); + let toTime = latestTime() + duration.days(15); + let expiryTime = toTime + duration.days(100); + let whitelisted = true; + + const tx1 = await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + assert.equal(tx1.logs[0].args._investor, NONACCREDITED1, "Failed in adding the investor in whitelist"); + const tx2 = await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + assert.equal(tx2.logs[0].args._investor, ACCREDITED1, "Failed in adding the investor in whitelist"); + }); + + it("should successfully modify accredited addresses for first STO", async() => { + let stoId = 0; + + let status1 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); + assert.equal(status1, false, "Initial accreditation is set to true"); + + await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1], [true], { from: ISSUER }); + let status2 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); + assert.equal(status2, true, "Failed to set single address"); + + await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [false, true], { from: ISSUER }); + let status3 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); + assert.equal(status3, false, "Failed to set multiple addresses"); + let status4 = await I_USDTieredSTO_Array[stoId].accredited.call(ACCREDITED1); + assert.equal(status4, true, "Failed to set multiple addresses"); + + await catchRevert(I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [true], { from: ISSUER })); + }); + + it("should successfully modify accredited addresses for second STO", async() => { + let stoId = 1; + + await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [false, true], { from: ISSUER }); + let status1 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); + let status2 = await I_USDTieredSTO_Array[stoId].accredited.call(ACCREDITED1); + assert.equal(status1, false, "Failed to set multiple address"); + assert.equal(status2, true, "Failed to set multiple address"); + }); + }); + + describe("Buy Tokens with no discount", async() => { + + it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await web3.eth.sendTransaction({ from: NONACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); + console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedUSD = await I_USDTieredSTO_Array[stoId].fundsRaisedUSD.call(); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), "Raised USD not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional checks on getters + assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, "Investor count not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), investment_Token.toNumber(), "getTokensSold not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), investment_Token.toNumber(), "getTokensMinted not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), investment_Token.toNumber(), "getTokensSoldForETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), 0, "getTokensSoldForPOLY not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), investment_USD.toNumber(), "investorInvestedUSD not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), investment_ETH.toNumber(), "investorInvestedETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), 0, "investorInvestedPOLY not changed as expected"); + }); + + it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised DAI not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using buyWithUSD at tier 0 for NONACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + let investment_DAI = investment_USD; + + await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_InvestorDAIBal = await I_DaiToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + // Buy With DAI + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithUSD: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_InvestorDAIBal = await I_DaiToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_RaisedDAI = await I_USDTieredSTO_Array[stoId].fundsRaised.call(DAI); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), "Investor DAI Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), "Wallet DAI Balance not changed as expected"); + }); + + it("should successfully buy using fallback at tier 0 for ACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + + await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await web3.eth.sendTransaction({ from: ACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); + console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + + // Additional checks on getters + let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_getTokensMinted = await I_USDTieredSTO_Array[stoId].getTokensMinted(); + let init_getTokensSoldForETH = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH); + let init_getTokensSoldForPOLY = await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY); + let init_investorInvestedUSD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1); + let init_investorInvestedETH = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH); + let init_investorInvestedPOLY = await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(ACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(ACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + + // Additional checks on getters + assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, "Investor count not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), init_getTokensSold.add(investment_Token).toNumber(), "getTokensSold not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), init_getTokensMinted.add(investment_Token).toNumber(), "getTokensMinted not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), init_getTokensSoldForETH.toNumber(), "getTokensSoldForETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), init_getTokensSoldForPOLY.add(investment_Token).toNumber(), "getTokensSoldForPOLY not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), init_investorInvestedUSD.add(investment_USD).toNumber(), "investorInvestedUSD not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), init_investorInvestedETH.toNumber(), "investorInvestedETH not changed as expected"); + assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), init_investorInvestedPOLY.add(investment_POLY).toNumber(), "investorInvestedPOLY not changed as expected"); + }); + + it("should successfully modify NONACCREDITED cap for NONACCREDITED1", async() => { + let stoId = 0; + let tierId = 0; + console.log("Current investment: " + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber()); + await I_USDTieredSTO_Array[stoId].changeNonAccreditedLimit([NONACCREDITED1], [_nonAccreditedLimitUSD[stoId].div(2)], {from: ISSUER}); + console.log("Current limit: " + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1)).toNumber()); + }); + + it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async() => { + let stoId = 0; + let tierId = 0; + + let investment_USD = (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1));//_nonAccreditedLimitUSD[stoId]; + let investment_Token = await convert(stoId, tierId, false, "USD", "TOKEN", investment_USD); + let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); + let investment_POLY = await convert(stoId, tierId, false, "USD", "POLY", investment_USD); + + let refund_USD = await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1); + let refund_Token = await convert(stoId, tierId, false, "USD", "TOKEN", refund_USD); + let refund_ETH = await convert(stoId, tierId, false, "USD", "ETH", refund_USD); + let refund_POLY = await convert(stoId, tierId, false, "USD", "POLY", refund_USD); + + console.log("Expected refund in tokens: " + refund_Token.toNumber()); + + let snap = await takeSnapshot(); + + let init_TokenSupply = await I_SecurityToken.totalSupply(); + let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy with ETH + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); + console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + + let final_TokenSupply = await I_SecurityToken.totalSupply(); + let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + let final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + let final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + let final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + let final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + let final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + let final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + let final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).add(refund_ETH).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).sub(refund_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).sub(refund_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); + + await revertToSnapshot(snap); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + + init_TokenSupply = await I_SecurityToken.totalSupply(); + init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + init_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + init_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + init_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + init_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + init_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + init_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + init_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + // Buy With POLY + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); + console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + + final_TokenSupply = await I_SecurityToken.totalSupply(); + final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); + final_InvestorETHBal = BigNumber(await web3.eth.getBalance(NONACCREDITED1)); + final_InvestorPOLYBal = await I_PolyToken.balanceOf(NONACCREDITED1); + final_STOTokenSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); + final_STOETHBal = BigNumber(await web3.eth.getBalance(I_USDTieredSTO_Array[stoId].address)); + final_STOPOLYBal = await I_PolyToken.balanceOf(I_USDTieredSTO_Array[stoId].address); + final_RaisedETH = await I_USDTieredSTO_Array[stoId].fundsRaised.call(ETH); + final_RaisedPOLY = await I_USDTieredSTO_Array[stoId].fundsRaised.call(POLY); + final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); + final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); + + assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); + assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); + assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); + assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).add(refund_POLY).toNumber(), "Investor POLY Balance not changed as expected"); + assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); + assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); + assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); + assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).sub(refund_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).sub(refund_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + }); + + it("should fail and revert when NONACCREDITED cap reached", async() => { + let stoId = 0; + let tierId = 0; + + let investment_Token = BigNumber(50).mul(10**18); + let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); + let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); + let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); + + await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1, gasPrice: GAS_PRICE}); + + // Buy with ETH NONACCREDITED + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + + // Buy with POLY NONACCREDITED + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); }); it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async () => { diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index ffc772631..6eb09defb 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -691,11 +691,21 @@ contract("USDTieredSTO Sim", accounts => { async function investFAIL(_investor) { let isPoly = Math.random() >= 0.3; let isDAI = Math.random() >= 0.3; - let investment_POLY = BigNumber(40 * 10 ** 18); // 10 USD = 40 POLY - let investment_ETH = BigNumber(0.02 * 10 ** 18); // 10 USD = 0.02 ETH - let investment_DAI = BigNumber(10 * 10 ** 18); // 10 USD = DAI DAI + let investment_POLY = BigNumber(40*10**18); // 10 USD = 40 POLY + let investment_ETH = BigNumber(0.02*10**18); // 10 USD = 0.02 ETH + let investment_DAI = BigNumber(10*10**18); // 10 USD = DAI DAI + + + if (isPoly) { + await I_PolyToken.getTokens(investment_POLY, _investor); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: _investor}); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE })); + } else if (isDAI) { + await I_DaiToken.getTokens(investment_DAI, _investor); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: _investor}); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE })); + } else await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE })); - await catchRevert(I_PolyToken.getTokens(investment_POLY, _investor)); } async function processInvestment( From 92bc715df59cc0c27d711a69b0c7bc07ef9e2ea6 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 11:24:03 +0530 Subject: [PATCH 066/142] Execute prettier --- test/h_general_transfer_manager.js | 22 +- test/p_usd_tiered_sto.js | 841 +++++++++++++++++++++-------- test/q_usd_tiered_sto_sim.js | 25 +- 3 files changed, 639 insertions(+), 249 deletions(-) diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 0c79b4348..65fc82c21 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -586,23 +586,25 @@ contract("GeneralTransferManager", accounts => { await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: account_delegate })); }); - it("Factory owner should pull fees", async() => { - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FEE_ADMIN", true, {from: token_owner}); + it("Factory owner should pull fees", async () => { + await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "FEE_ADMIN", true, { + from: token_owner + }); let balanceBefore = await I_PolyToken.balanceOf(account_polymath); - await I_GeneralTransferManager.takeFee(web3.utils.toWei('1','ether'), {from: account_delegate}); + await I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: account_delegate }); let balanceAfter = await I_PolyToken.balanceOf(account_polymath); - assert.equal(balanceBefore.add(web3.utils.toWei('1','ether')).toNumber(), balanceAfter.toNumber(), "Fee is transferred"); + assert.equal(balanceBefore.add(web3.utils.toWei("1", "ether")).toNumber(), balanceAfter.toNumber(), "Fee is transferred"); }); - it("Should change the white list transfer variable", async() => { - let tx = await I_GeneralTransferManager.changeAllowAllWhitelistIssuances(true, {from : token_owner}); + it("Should change the white list transfer variable", async () => { + let tx = await I_GeneralTransferManager.changeAllowAllWhitelistIssuances(true, { from: token_owner }); assert.isTrue(tx.logs[0].args._allowAllWhitelistIssuances); }); - it("should failed in trasfering the tokens", async() => { - let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from : token_owner}); - await I_GeneralTransferManager.pause({from: token_owner}); - await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2','ether'), {from: account_investor2})); + it("should failed in trasfering the tokens", async () => { + let tx = await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, { from: token_owner }); + await I_GeneralTransferManager.pause({ from: token_owner }); + await catchRevert(I_SecurityToken.transfer(account_investor1, web3.utils.toWei("2", "ether"), { from: account_investor2 })); }); it("Should change the Issuance address", async () => { diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 9caee056d..48099a17f 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -978,11 +978,11 @@ contract("USDTieredSTO", accounts => { }); describe("Test buying failure conditions", async () => { - it("should fail if before STO start time", async() => { + it("should fail if before STO start time", async () => { let stoId = 0; let snapId = await takeSnapshot(); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, "STO is not showing correct status"); // Whitelist let fromTime = latestTime(); @@ -990,8 +990,8 @@ contract("USDTieredSTO", accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); // // Advance time to after STO start // await increaseTime(duration.days(3)); @@ -1000,40 +1000,40 @@ contract("USDTieredSTO", accounts => { await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + let investment_ETH = web3.utils.toWei("1", "ether"); // Invest 1 ETH + let investment_POLY = web3.utils.toWei("10000", "ether"); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + let investment_DAI = web3.utils.toWei("500", "ether"); // Invest 10000 POLY await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // NONACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // NONACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); - + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1 })); + // NONACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1 })); // ACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); - + // ACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1 })); // ACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1 })); await revertToSnapshot(snapId); }); - it("should fail if not whitelisted", async() => { + it("should fail if not whitelisted", async () => { let stoId = 0; let snapId = await takeSnapshot(); @@ -1053,40 +1053,40 @@ contract("USDTieredSTO", accounts => { await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + let investment_ETH = web3.utils.toWei("1", "ether"); // Invest 1 ETH + let investment_POLY = web3.utils.toWei("10000", "ether"); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + let investment_DAI = web3.utils.toWei("500", "ether"); // Invest 10000 POLY await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // NONACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // NONACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1 })); // NONACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); - + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1 })); + // ACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); // ACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1 })); // ACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1 })); await revertToSnapshot(snapId); }); - it("should fail if minimumInvestmentUSD not met", async() => { + it("should fail if minimumInvestmentUSD not met", async () => { let stoId = 0; let tierId = 0; let snapId = await takeSnapshot(); @@ -1097,8 +1097,8 @@ contract("USDTieredSTO", accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); // Advance time to after STO start await increaseTime(duration.days(3)); @@ -1106,44 +1106,43 @@ contract("USDTieredSTO", accounts => { // Set as accredited await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - let investment_USD = BigNumber(2).mul(10**18); - let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); + let investment_USD = BigNumber(2).mul(10 ** 18); + let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); let investment_POLY = await convert(stoId, tierId, false, "USD", "POLY", investment_USD); let investment_DAI = investment_USD; await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // NONACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // NONACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1 })); // NONACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); - + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1 })); + // ACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); // ACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1 })); // ACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1 })); await revertToSnapshot(snapId); }); - it("should successfully pause the STO and make investments fail, then unpause and succeed", async() => { + it("should successfully pause the STO and make investments fail, then unpause and succeed", async () => { let stoId = 0; let snapId = await takeSnapshot(); @@ -1153,8 +1152,8 @@ contract("USDTieredSTO", accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); // Advance time to after STO start await increaseTime(duration.days(3)); @@ -1164,56 +1163,56 @@ contract("USDTieredSTO", accounts => { // Pause the STO await I_USDTieredSTO_Array[stoId].pause({ from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), true, 'STO did not pause successfully'); + assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), true, "STO did not pause successfully"); // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + let investment_ETH = web3.utils.toWei("1", "ether"); // Invest 1 ETH + let investment_POLY = web3.utils.toWei("10000", "ether"); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + let investment_DAI = web3.utils.toWei("500", "ether"); // Invest 10000 POLY await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // NONACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // NONACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1 })); // NONACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); - + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1 })); + // ACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); // ACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1 })); // ACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1 })); // Unpause the STO await I_USDTieredSTO_Array[stoId].unpause({ from: ISSUER }); - assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), false, 'STO did not unpause successfully'); + assert.equal(await I_USDTieredSTO_Array[stoId].paused.call(), false, "STO did not unpause successfully"); await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH }); - await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1}); - await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1}); + await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1 }); + await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1 }); await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH }); - await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1}); - await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1}); + await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1 }); + await I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1 }); await revertToSnapshot(snapId); }); - it("should fail if after STO end time", async() => { + it("should fail if after STO end time", async () => { let stoId = 3; let snapId = await takeSnapshot(); @@ -1223,53 +1222,52 @@ contract("USDTieredSTO", accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); // Advance time to after STO end await increaseTime(duration.days(3)); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, "STO is not showing correct status"); // Set as accredited await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + let investment_ETH = web3.utils.toWei("1", "ether"); // Invest 1 ETH + let investment_POLY = web3.utils.toWei("10000", "ether"); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + let investment_DAI = web3.utils.toWei("500", "ether"); // Invest 10000 POLY await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); - + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // NONACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // NONACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1 })); // NONACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); - + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1 })); + // ACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); // ACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1 })); // ACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1 })); await revertToSnapshot(snapId); }); - it("should fail if finalized", async() => { + it("should fail if finalized", async () => { let stoId = 0; let snapId = await takeSnapshot(); @@ -1279,9 +1277,9 @@ contract("USDTieredSTO", accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); - await I_GeneralTransferManager.modifyWhitelist(RESERVEWALLET, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); + await I_GeneralTransferManager.modifyWhitelist(RESERVEWALLET, fromTime, toTime, expiryTime, whitelisted, { from: ISSUER }); // Advance time to after STO start await increaseTime(duration.days(3)); @@ -1292,55 +1290,54 @@ contract("USDTieredSTO", accounts => { // Finalize STO await I_USDTieredSTO_Array[stoId].finalize({ from: ISSUER }); assert.equal(await I_USDTieredSTO_Array[stoId].isFinalized.call(), true, "STO has not been finalized"); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),false,"STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), false, "STO is not showing correct status"); // Attempt to call function again await catchRevert(I_USDTieredSTO_Array[stoId].finalize({ from: ISSUER })); // Prep for investments - let investment_ETH = web3.utils.toWei('1', 'ether'); // Invest 1 ETH - let investment_POLY = web3.utils.toWei('10000', 'ether'); // Invest 10000 POLY + let investment_ETH = web3.utils.toWei("1", "ether"); // Invest 1 ETH + let investment_POLY = web3.utils.toWei("10000", "ether"); // Invest 10000 POLY await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); - let investment_DAI = web3.utils.toWei('500', 'ether'); // Invest 10000 POLY + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); + let investment_DAI = web3.utils.toWei("500", "ether"); // Invest 10000 POLY await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); await I_DaiToken.getTokens(investment_DAI, ACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: ACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: ACCREDITED1 }); // NONACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH })); // NONACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, {from: NONACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1 })); // NONACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, {from: NONACCREDITED1})); - + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1 })); + // ACCREDITED ETH await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH })); // ACCREDITED POLY - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1 })); // ACCREDITED DAI - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, {from: ACCREDITED1})); + await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(ACCREDITED1, investment_DAI, { from: ACCREDITED1 })); await revertToSnapshot(snapId); }); }); - describe("Prep STO", async() => { - - it("should jump forward to after STO start", async() => { + describe("Prep STO", async () => { + it("should jump forward to after STO start", async () => { let stoId = 0; await increaseTime(duration.days(3)); - assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(),true,"STO is not showing correct status"); + assert.equal(await I_USDTieredSTO_Array[stoId].isOpen(), true, "STO is not showing correct status"); }); - it("should whitelist ACCREDITED1 and NONACCREDITED1", async() => { + it("should whitelist ACCREDITED1 and NONACCREDITED1", async () => { let stoId = 0; let fromTime = latestTime(); @@ -1348,13 +1345,17 @@ contract("USDTieredSTO", accounts => { let expiryTime = toTime + duration.days(100); let whitelisted = true; - const tx1 = await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + const tx1 = await I_GeneralTransferManager.modifyWhitelist(NONACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { + from: ISSUER + }); assert.equal(tx1.logs[0].args._investor, NONACCREDITED1, "Failed in adding the investor in whitelist"); - const tx2 = await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted,{ from: ISSUER }); + const tx2 = await I_GeneralTransferManager.modifyWhitelist(ACCREDITED1, fromTime, toTime, expiryTime, whitelisted, { + from: ISSUER + }); assert.equal(tx2.logs[0].args._investor, ACCREDITED1, "Failed in adding the investor in whitelist"); }); - it("should successfully modify accredited addresses for first STO", async() => { + it("should successfully modify accredited addresses for first STO", async () => { let stoId = 0; let status1 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); @@ -1373,7 +1374,7 @@ contract("USDTieredSTO", accounts => { await catchRevert(I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [true], { from: ISSUER })); }); - it("should successfully modify accredited addresses for second STO", async() => { + it("should successfully modify accredited addresses for second STO", async () => { let stoId = 1; await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [false, true], { from: ISSUER }); @@ -1384,13 +1385,12 @@ contract("USDTieredSTO", accounts => { }); }); - describe("Buy Tokens with no discount", async() => { - - it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async() => { + describe("Buy Tokens with no discount", async () => { + it("should successfully buy using fallback at tier 0 for NONACCREDITED1", async () => { let stoId = 0; let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1409,9 +1409,15 @@ contract("USDTieredSTO", accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await web3.eth.sendTransaction({ from: NONACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let tx1 = await web3.eth.sendTransaction({ + from: NONACCREDITED1, + to: I_USDTieredSTO_Array[stoId].address, + value: investment_ETH, + gasPrice: GAS_PRICE, + gas: 1000000 + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + console.log(" Gas fallback purchase: ".grey + tx1.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1427,36 +1433,91 @@ contract("USDTieredSTO", accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedUSD.toNumber(), init_RaisedUSD.add(investment_USD).toNumber(), "Raised USD not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); // Additional checks on getters assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 1, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), investment_Token.toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), investment_Token.toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), investment_Token.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), 0, "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), investment_USD.toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), investment_ETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), 0, "investorInvestedPOLY not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), + investment_Token.toNumber(), + "getTokensSold not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), + investment_Token.toNumber(), + "getTokensMinted not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), + investment_Token.toNumber(), + "getTokensSoldForETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), + 0, + "getTokensSoldForPOLY not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber(), + investment_USD.toNumber(), + "investorInvestedUSD not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, ETH)).toNumber(), + investment_ETH.toNumber(), + "investorInvestedETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(NONACCREDITED1, POLY)).toNumber(), + 0, + "investorInvestedPOLY not changed as expected" + ); }); - it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async() => { + it("should successfully buy using buyWithETH at tier 0 for NONACCREDITED1", async () => { let stoId = 0; let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1474,9 +1535,13 @@ contract("USDTieredSTO", accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithETH: ".grey + tx1.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1491,31 +1556,58 @@ contract("USDTieredSTO", accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised DAI not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); }); - it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async() => { + it("should successfully buy using buyWithPOLY at tier 0 for NONACCREDITED1", async () => { let stoId = 0; let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); let init_TokenSupply = await I_SecurityToken.totalSupply(); let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1531,9 +1623,12 @@ contract("USDTieredSTO", accounts => { let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1548,32 +1643,60 @@ contract("USDTieredSTO", accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.toNumber(), "Raised POLY not changed as expected"); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); }); - it("should successfully buy using buyWithUSD at tier 0 for NONACCREDITED1", async() => { + it("should successfully buy using buyWithUSD at tier 0 for NONACCREDITED1", async () => { let stoId = 0; let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); let investment_DAI = investment_USD; await I_DaiToken.getTokens(investment_DAI, NONACCREDITED1); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: NONACCREDITED1}); + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: NONACCREDITED1 }); let init_TokenSupply = await I_SecurityToken.totalSupply(); let init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1591,9 +1714,12 @@ contract("USDTieredSTO", accounts => { let init_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); // Buy With DAI - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithUSD(NONACCREDITED1, investment_DAI, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithUSD: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithUSD: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1610,12 +1736,36 @@ contract("USDTieredSTO", accounts => { let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); let final_WalletDAIBal = await I_DaiToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_InvestorDAIBal.toNumber(), init_InvestorDAIBal.sub(investment_DAI).toNumber(), "Investor DAI Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_InvestorDAIBal.toNumber(), + init_InvestorDAIBal.sub(investment_DAI).toNumber(), + "Investor DAI Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); @@ -1623,16 +1773,20 @@ contract("USDTieredSTO", accounts => { assert.equal(final_RaisedDAI.toNumber(), init_RaisedDAI.add(investment_DAI).toNumber(), "Raised POLY not changed as expected"); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); - assert.equal(final_WalletDAIBal.toNumber(), init_WalletDAIBal.add(investment_DAI).toNumber(), "Wallet DAI Balance not changed as expected"); + assert.equal( + final_WalletDAIBal.toNumber(), + init_WalletDAIBal.add(investment_DAI).toNumber(), + "Wallet DAI Balance not changed as expected" + ); }); - it("should successfully buy using fallback at tier 0 for ACCREDITED1", async() => { + it("should successfully buy using fallback at tier 0 for ACCREDITED1", async () => { let stoId = 0; let tierId = 0; await I_USDTieredSTO_Array[stoId].changeAccredited([ACCREDITED1], [true], { from: ISSUER }); - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1649,9 +1803,15 @@ contract("USDTieredSTO", accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await web3.eth.sendTransaction({ from: ACCREDITED1, to: I_USDTieredSTO_Array[stoId].address, value: investment_ETH, gasPrice: GAS_PRICE, gas:1000000 }); + let tx1 = await web3.eth.sendTransaction({ + from: ACCREDITED1, + to: I_USDTieredSTO_Array[stoId].address, + value: investment_ETH, + gasPrice: GAS_PRICE, + gas: 1000000 + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.gasUsed); - console.log(" Gas fallback purchase: ".grey+tx1.gasUsed.toString().grey); + console.log(" Gas fallback purchase: ".grey + tx1.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1665,24 +1825,51 @@ contract("USDTieredSTO", accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); }); - it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async() => { + it("should successfully buy using buyWithETH at tier 0 for ACCREDITED1", async () => { let stoId = 0; let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); @@ -1699,9 +1886,13 @@ contract("USDTieredSTO", accounts => { let init_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { from: ACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(ACCREDITED1, { + from: ACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithETH: ".grey + tx1.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1715,30 +1906,57 @@ contract("USDTieredSTO", accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).toNumber(), "Raised ETH not changed as expected"); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal.add(investment_ETH).toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); }); - it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async() => { + it("should successfully buy using buyWithPOLY at tier 0 for ACCREDITED1", async () => { let stoId = 0; let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); await I_PolyToken.getTokens(investment_POLY, ACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: ACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: ACCREDITED1 }); // Additional checks on getters let init_getTokensSold = await I_USDTieredSTO_Array[stoId].getTokensSold(); @@ -1762,9 +1980,12 @@ contract("USDTieredSTO", accounts => { let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { from: ACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, { + from: ACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(ACCREDITED1); @@ -1778,42 +1999,100 @@ contract("USDTieredSTO", accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply.add(investment_Token).toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal.add(investment_Token).toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.sub(investment_POLY).toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold.add(investment_Token).toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY.add(investment_POLY).toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal.add(investment_POLY).toNumber(), + "Wallet POLY Balance not changed as expected" + ); // Additional checks on getters assert.equal((await I_USDTieredSTO_Array[stoId].investorCount.call()).toNumber(), 2, "Investor count not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), init_getTokensSold.add(investment_Token).toNumber(), "getTokensSold not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), init_getTokensMinted.add(investment_Token).toNumber(), "getTokensMinted not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), init_getTokensSoldForETH.toNumber(), "getTokensSoldForETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), init_getTokensSoldForPOLY.add(investment_Token).toNumber(), "getTokensSoldForPOLY not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), init_investorInvestedUSD.add(investment_USD).toNumber(), "investorInvestedUSD not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), init_investorInvestedETH.toNumber(), "investorInvestedETH not changed as expected"); - assert.equal((await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), init_investorInvestedPOLY.add(investment_POLY).toNumber(), "investorInvestedPOLY not changed as expected"); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSold()).toNumber(), + init_getTokensSold.add(investment_Token).toNumber(), + "getTokensSold not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensMinted()).toNumber(), + init_getTokensMinted.add(investment_Token).toNumber(), + "getTokensMinted not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(ETH)).toNumber(), + init_getTokensSoldForETH.toNumber(), + "getTokensSoldForETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].getTokensSoldFor(POLY)).toNumber(), + init_getTokensSoldForPOLY.add(investment_Token).toNumber(), + "getTokensSoldForPOLY not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(ACCREDITED1)).toNumber(), + init_investorInvestedUSD.add(investment_USD).toNumber(), + "investorInvestedUSD not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, ETH)).toNumber(), + init_investorInvestedETH.toNumber(), + "investorInvestedETH not changed as expected" + ); + assert.equal( + (await I_USDTieredSTO_Array[stoId].investorInvested.call(ACCREDITED1, POLY)).toNumber(), + init_investorInvestedPOLY.add(investment_POLY).toNumber(), + "investorInvestedPOLY not changed as expected" + ); }); - it("should successfully modify NONACCREDITED cap for NONACCREDITED1", async() => { + it("should successfully modify NONACCREDITED cap for NONACCREDITED1", async () => { let stoId = 0; let tierId = 0; console.log("Current investment: " + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber()); - await I_USDTieredSTO_Array[stoId].changeNonAccreditedLimit([NONACCREDITED1], [_nonAccreditedLimitUSD[stoId].div(2)], {from: ISSUER}); + await I_USDTieredSTO_Array[stoId].changeNonAccreditedLimit([NONACCREDITED1], [_nonAccreditedLimitUSD[stoId].div(2)], { + from: ISSUER + }); console.log("Current limit: " + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1)).toNumber()); }); - it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async() => { + it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async () => { let stoId = 0; let tierId = 0; - let investment_USD = (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1));//_nonAccreditedLimitUSD[stoId]; + let investment_USD = await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1); //_nonAccreditedLimitUSD[stoId]; let investment_Token = await convert(stoId, tierId, false, "USD", "TOKEN", investment_USD); let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); let investment_POLY = await convert(stoId, tierId, false, "USD", "POLY", investment_USD); @@ -1840,9 +2119,13 @@ contract("USDTieredSTO", accounts => { let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy with ETH - let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }); + let tx1 = await I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { + from: NONACCREDITED1, + value: investment_ETH, + gasPrice: GAS_PRICE + }); let gasCost1 = BigNumber(GAS_PRICE).mul(tx1.receipt.gasUsed); - console.log(" Gas buyWithETH: ".grey+tx1.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithETH: ".grey + tx1.receipt.gasUsed.toString().grey); let final_TokenSupply = await I_SecurityToken.totalSupply(); let final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1856,22 +2139,69 @@ contract("USDTieredSTO", accounts => { let final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); let final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost1).sub(investment_ETH).add(refund_ETH).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal + .sub(gasCost1) + .sub(investment_ETH) + .add(refund_ETH) + .toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal.toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); - assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.add(investment_ETH).sub(refund_ETH).toNumber(), "Raised ETH not changed as expected"); + assert.equal( + final_RaisedETH.toNumber(), + init_RaisedETH + .add(investment_ETH) + .sub(refund_ETH) + .toNumber(), + "Raised ETH not changed as expected" + ); assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.toNumber(), "Raised POLY not changed as expected"); - assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.add(investment_ETH).sub(refund_ETH).toNumber(), "Wallet ETH Balance not changed as expected"); + assert.equal( + final_WalletETHBal.toNumber(), + init_WalletETHBal + .add(investment_ETH) + .sub(refund_ETH) + .toNumber(), + "Wallet ETH Balance not changed as expected" + ); assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.toNumber(), "Wallet POLY Balance not changed as expected"); await revertToSnapshot(snap); await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1 }); init_TokenSupply = await I_SecurityToken.totalSupply(); init_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1886,9 +2216,12 @@ contract("USDTieredSTO", accounts => { init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); // Buy With POLY - let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); + let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { + from: NONACCREDITED1, + gasPrice: GAS_PRICE + }); let gasCost2 = BigNumber(GAS_PRICE).mul(tx2.receipt.gasUsed); - console.log(" Gas buyWithPOLY: ".grey+tx2.receipt.gasUsed.toString().grey); + console.log(" Gas buyWithPOLY: ".grey + tx2.receipt.gasUsed.toString().grey); final_TokenSupply = await I_SecurityToken.totalSupply(); final_InvestorTokenBal = await I_SecurityToken.balanceOf(NONACCREDITED1); @@ -1902,36 +2235,86 @@ contract("USDTieredSTO", accounts => { final_WalletETHBal = BigNumber(await web3.eth.getBalance(WALLET)); final_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET); - assert.equal(final_TokenSupply.toNumber(), init_TokenSupply.add(investment_Token).sub(refund_Token).toNumber(), "Token Supply not changed as expected"); - assert.equal(final_InvestorTokenBal.toNumber(), init_InvestorTokenBal.add(investment_Token).sub(refund_Token).toNumber(), "Investor Token Balance not changed as expected"); - assert.equal(final_InvestorETHBal.toNumber(), init_InvestorETHBal.sub(gasCost2).toNumber(), "Investor ETH Balance not changed as expected"); - assert.equal(final_InvestorPOLYBal.toNumber(), init_InvestorPOLYBal.sub(investment_POLY).add(refund_POLY).toNumber(), "Investor POLY Balance not changed as expected"); - assert.equal(final_STOTokenSold.toNumber(), init_STOTokenSold.add(investment_Token).sub(refund_Token).toNumber(), "STO Token Sold not changed as expected"); + assert.equal( + final_TokenSupply.toNumber(), + init_TokenSupply + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "Token Supply not changed as expected" + ); + assert.equal( + final_InvestorTokenBal.toNumber(), + init_InvestorTokenBal + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "Investor Token Balance not changed as expected" + ); + assert.equal( + final_InvestorETHBal.toNumber(), + init_InvestorETHBal.sub(gasCost2).toNumber(), + "Investor ETH Balance not changed as expected" + ); + assert.equal( + final_InvestorPOLYBal.toNumber(), + init_InvestorPOLYBal + .sub(investment_POLY) + .add(refund_POLY) + .toNumber(), + "Investor POLY Balance not changed as expected" + ); + assert.equal( + final_STOTokenSold.toNumber(), + init_STOTokenSold + .add(investment_Token) + .sub(refund_Token) + .toNumber(), + "STO Token Sold not changed as expected" + ); assert.equal(final_STOETHBal.toNumber(), init_STOETHBal.toNumber(), "STO ETH Balance not changed as expected"); assert.equal(final_STOPOLYBal.toNumber(), init_STOPOLYBal.toNumber(), "STO POLY Balance not changed as expected"); assert.equal(final_RaisedETH.toNumber(), init_RaisedETH.toNumber(), "Raised ETH not changed as expected"); - assert.equal(final_RaisedPOLY.toNumber(), init_RaisedPOLY.add(investment_POLY).sub(refund_POLY).toNumber(), "Raised POLY not changed as expected"); + assert.equal( + final_RaisedPOLY.toNumber(), + init_RaisedPOLY + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + "Raised POLY not changed as expected" + ); assert.equal(final_WalletETHBal.toNumber(), init_WalletETHBal.toNumber(), "Wallet ETH Balance not changed as expected"); - assert.equal(final_WalletPOLYBal.toNumber(), init_WalletPOLYBal.add(investment_POLY).sub(refund_POLY).toNumber(), "Wallet POLY Balance not changed as expected"); + assert.equal( + final_WalletPOLYBal.toNumber(), + init_WalletPOLYBal + .add(investment_POLY) + .sub(refund_POLY) + .toNumber(), + "Wallet POLY Balance not changed as expected" + ); }); - it("should fail and revert when NONACCREDITED cap reached", async() => { + it("should fail and revert when NONACCREDITED cap reached", async () => { let stoId = 0; let tierId = 0; - let investment_Token = BigNumber(50).mul(10**18); + let investment_Token = BigNumber(50).mul(10 ** 18); let investment_USD = await convert(stoId, tierId, false, "TOKEN", "USD", investment_Token); let investment_ETH = await convert(stoId, tierId, false, "TOKEN", "ETH", investment_Token); let investment_POLY = await convert(stoId, tierId, false, "TOKEN", "POLY", investment_Token); await I_PolyToken.getTokens(investment_POLY, NONACCREDITED1); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: NONACCREDITED1, gasPrice: GAS_PRICE}); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }); // Buy with ETH NONACCREDITED - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE })); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(NONACCREDITED1, { from: NONACCREDITED1, value: investment_ETH, gasPrice: GAS_PRICE }) + ); // Buy with POLY NONACCREDITED - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE })); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(NONACCREDITED1, investment_POLY, { from: NONACCREDITED1, gasPrice: GAS_PRICE }) + ); }); it("should fail and revert despite oracle price change when NONACCREDITED cap reached", async () => { diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index 6eb09defb..e8c1b8a9f 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -691,21 +691,26 @@ contract("USDTieredSTO Sim", accounts => { async function investFAIL(_investor) { let isPoly = Math.random() >= 0.3; let isDAI = Math.random() >= 0.3; - let investment_POLY = BigNumber(40*10**18); // 10 USD = 40 POLY - let investment_ETH = BigNumber(0.02*10**18); // 10 USD = 0.02 ETH - let investment_DAI = BigNumber(10*10**18); // 10 USD = DAI DAI - + let investment_POLY = BigNumber(40 * 10 ** 18); // 10 USD = 40 POLY + let investment_ETH = BigNumber(0.02 * 10 ** 18); // 10 USD = 0.02 ETH + let investment_DAI = BigNumber(10 * 10 ** 18); // 10 USD = DAI DAI if (isPoly) { await I_PolyToken.getTokens(investment_POLY, _investor); - await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, {from: _investor}); - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE })); + await I_PolyToken.approve(I_USDTieredSTO_Array[stoId].address, investment_POLY, { from: _investor }); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithPOLY(_investor, investment_POLY, { from: _investor, gasPrice: GAS_PRICE }) + ); } else if (isDAI) { await I_DaiToken.getTokens(investment_DAI, _investor); - await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, {from: _investor}); - await catchRevert(I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE })); - } else await catchRevert(I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE })); - + await I_DaiToken.approve(I_USDTieredSTO_Array[stoId].address, investment_DAI, { from: _investor }); + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithUSD(_investor, investment_DAI, { from: _investor, gasPrice: GAS_PRICE }) + ); + } else + await catchRevert( + I_USDTieredSTO_Array[stoId].buyWithETH(_investor, { from: _investor, value: investment_ETH, gasPrice: GAS_PRICE }) + ); } async function processInvestment( From abd94779bfc22ebbc520718512abc3e0a6fc3f84 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 11:24:40 +0530 Subject: [PATCH 067/142] minor fix in changePermissionMulti --- .../PermissionManager/GeneralPermissionManager.sol | 9 +++++---- .../modules/PermissionManager/IPermissionManager.sol | 4 +++- test/g_general_permission_manager.js | 6 +----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 1d78e0c08..849fe0094 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -106,22 +106,23 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @param _delegate Ethereum address of the delegate * @param _modules Multiple module matching the multiperms, needs to be same length * @param _perms Multiple permission flag needs to be changed + * @param _valids Bool array consist the flag to switch on/off the permission * @return nothing */ function changePermissionMulti( address _delegate, address[] _modules, - bytes32[] _perms + bytes32[] _perms, + bool[] _valids ) external withPerm(CHANGE_PERMISSION) { require(_modules.length > 0 && _perms.length > 0, "0 length is not allowed"); require(_modules.length == _perms.length, "Array length mismatch"); - + require(_valids.length == _perms.length, "Array length mismatch"); for(uint8 i = 0; i < _perms.length; i++) { - bool _perm = !perms[_modules[i]][_delegate][_perms[i]]; - changePermission(_delegate, _modules[i], _perms[i], _perm); + changePermission(_delegate, _modules[i], _perms[i], _valids[i]); } } diff --git a/contracts/modules/PermissionManager/IPermissionManager.sol b/contracts/modules/PermissionManager/IPermissionManager.sol index 83493d0af..2b9c93ee8 100644 --- a/contracts/modules/PermissionManager/IPermissionManager.sol +++ b/contracts/modules/PermissionManager/IPermissionManager.sol @@ -49,12 +49,14 @@ interface IPermissionManager { * @param _delegate Ethereum address of the delegate * @param _modules Multiple module matching the multiperms, needs to be same length * @param _perms Multiple permission flag needs to be changed + * @param _valids Bool array consist the flag to switch on/off the permission * @return nothing */ function changePermissionMulti( address _delegate, address[] _modules, - bytes32[] _perms + bytes32[] _perms, + bool[] _valids ) external; diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index a18cf5cbf..b04f8a18d 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -432,7 +432,7 @@ contract('GeneralPermissionManager', accounts => { it("Should provide the permission in bulk", async() => { await I_GeneralPermissionManager.addDelegate(account_delegate3, delegateDetails, { from: token_owner}); - let tx = await I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], ["WHITELIST","CHANGE_PERMISSION"], {from: token_owner}); + let tx = await I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], ["WHITELIST","CHANGE_PERMISSION"], [true, true], {from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate3); assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate3, I_GeneralTransferManager.address, "WHITELIST")); @@ -462,10 +462,6 @@ contract('GeneralPermissionManager', accounts => { }); - - - - }); describe("General Permission Manager Factory test cases", async() => { From 77f829d881ad927e00993c35a900d36552ccd4e6 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 11:28:21 +0530 Subject: [PATCH 068/142] Removed ex.js --- ex.js | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 ex.js diff --git a/ex.js b/ex.js deleted file mode 100644 index 570a48ee2..000000000 --- a/ex.js +++ /dev/null @@ -1,24 +0,0 @@ -var fs = require('fs') -const regex = /(?<=try {)(.*?)(await )(.*?)(?=;)(.*?)(?=message\);)/gmis; -const regex2 = /(try {)(.*?)(message\);)/gmis; -const regex3 = /(let errorThrown. = false;)/gmis; -const dirname = 'test/'; - -fs.readdir(dirname, function(err, filenames) { - if (err) { - return console.log(err); - } - filenames.forEach(function(filename) { - fs.readFile(dirname + filename, 'utf-8', function(err, content) { - if (err) { - return console.log(err); - } - content = content.replace(regex, 'catchRevert($3);'); - content = content.replace(regex2, 'await $2'); - content = content.replace(regex3, ''); - fs.writeFile(dirname + filename, content, 'utf8', function (err) { - if (err) return console.log(err); - }); - }); - }); -}); \ No newline at end of file From e50e690f8a26ce75100ba72057dc712325bc5383 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 12:12:17 +0530 Subject: [PATCH 069/142] Disabled deepSkip to fix coverage --- .solcover.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.solcover.js b/.solcover.js index 5f1828c6b..7284ec15f 100644 --- a/.solcover.js +++ b/.solcover.js @@ -3,6 +3,6 @@ module.exports = { port: 8545, copyPackages: ['openzeppelin-solidity'], testCommand: 'node ../node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` --network coverage', - deepSkip: true, + deepSkip: false, skipFiles: ['external', 'flat', 'mocks', 'helpers', 'oracles'] }; From 487624fc124aefff97ac16746479149a0faa31ca Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 12:53:24 +0530 Subject: [PATCH 070/142] Coverage config changed --- .solcover.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.solcover.js b/.solcover.js index 7284ec15f..5d4677512 100644 --- a/.solcover.js +++ b/.solcover.js @@ -3,6 +3,6 @@ module.exports = { port: 8545, copyPackages: ['openzeppelin-solidity'], testCommand: 'node ../node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` --network coverage', - deepSkip: false, - skipFiles: ['external', 'flat', 'mocks', 'helpers', 'oracles'] + deepSkip: true, + skipFiles: ['external', 'flat', 'helpers'] }; From 5d56a51e6c99d117b79249dcd1682baf62176bac Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 13:31:15 +0530 Subject: [PATCH 071/142] remove cruft --- test/f_ether_dividends.js | 45 --------------------------------------- 1 file changed, 45 deletions(-) diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index aff9c6f49..d6760e011 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -97,51 +97,6 @@ contract('EtherDividendCheckpoint', accounts => { account_investor4 = accounts[9]; account_temp = accounts[2]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); // STEP 4: Deploy the ERC20DividendCheckpoint P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); From 903044ae193d96caaa7679ddb1164dea3c4847e2 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 13:46:53 +0530 Subject: [PATCH 072/142] remove repeatitive code --- test/f_ether_dividends.js | 100 ++++++++++---------------------------- 1 file changed, 27 insertions(+), 73 deletions(-) diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 115a4cd5c..215b2deba 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -3,22 +3,12 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); const EtherDividendCheckpoint = artifacts.require("./EtherDividendCheckpoint"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -44,7 +34,6 @@ contract("EtherDividendCheckpoint", accounts => { let dividendName = "0x546573744469766964656e640000000000000000000000000000000000000000"; // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; let I_SecurityTokenRegistryProxy; let I_GeneralTransferManagerFactory; let P_EtherDividendCheckpointFactory; @@ -53,7 +42,6 @@ contract("EtherDividendCheckpoint", accounts => { let I_GeneralPermissionManager; let I_EtherDividendCheckpoint; let I_GeneralTransferManager; - let I_ExchangeTransferManager; let I_ModuleRegistryProxy; let I_ModuleRegistry; let I_FeatureRegistry; @@ -80,8 +68,6 @@ contract("EtherDividendCheckpoint", accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; before(async () => { // Accounts setup @@ -96,6 +82,23 @@ contract("EtherDividendCheckpoint", accounts => { account_investor4 = accounts[9]; account_temp = accounts[2]; + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + // STEP 4: Deploy the ERC20DividendCheckpoint P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new( @@ -121,54 +124,6 @@ contract("EtherDividendCheckpoint", accounts => { "EtherDividendCheckpointFactory contract was not deployed" ); - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the EtherDividendCheckpointFactory await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); @@ -180,16 +135,15 @@ contract("EtherDividendCheckpoint", accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} EtherDividendCheckpointFactory: ${I_EtherDividendCheckpointFactory.address} ----------------------------------------------------------------------------- From f6f452670ed62529e3dfa56c16a5b5a5c55db4c8 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 14:04:01 +0530 Subject: [PATCH 073/142] cleanup GPM --- test/g_general_permission_manager.js | 125 ++++++--------------------- 1 file changed, 28 insertions(+), 97 deletions(-) diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index a7d2b2ee2..1bc9dcb71 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -5,22 +5,14 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const DummySTO = artifacts.require("./DummySTO.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -87,8 +79,6 @@ contract("GeneralPermissionManager", accounts => { const cap = web3.utils.toWei("10", "ether"); const someString = "A string which is not used"; const STOParameters = ["uint256", "uint256", "uint256", "string"]; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); @@ -104,39 +94,23 @@ contract("GeneralPermissionManager", accounts => { account_investor2 = accounts[9]; account_delegate = accounts[7]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + // STEP 5: Deploy the GeneralDelegateManagerFactory @@ -176,49 +150,6 @@ contract("GeneralPermissionManager", accounts => { "DummySTOFactory contract was not deployed" ); - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 8: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); // (B) : Register the GeneralDelegateManagerFactory await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); @@ -235,16 +166,16 @@ contract("GeneralPermissionManager", accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- From fff2ddda73572fbac9ea2bf314a8f102ea89c3d4 Mon Sep 17 00:00:00 2001 From: Chris Cassano <1285652+glitch003@users.noreply.github.com> Date: Fri, 5 Oct 2018 01:38:06 -0700 Subject: [PATCH 074/142] Lockup Volume Restrictions (#290) * first commit. contracts compile, but need to write tests * basic tests pass * more tests * more tests * more tests * better tests * more coverage * missed one branch of coverage. this should fix it * put back old package-lock.json * comment fix * added one more test * make transfer fail if lockup startTime hasn't passed yet * merged dev-1.5.0 latest in and fixed tests to work with that * put back old package-lock.json * add newline to end of package-lock.json to clean up PR * code in place to track balances per lockup. but i don't think this will work long term so moving it into this branch * made changes requested * changed to store withdrawn balances inside each lockup * rename test * updated before hook to use new stuff so that tests will run * Added a test case * make releaseFrequencySeconds a bit longer in a test so that the tests are happier on travis * Update VolumeRestrictionTransferManager.sol * Update w_volume_restriction_transfer_manager.js * fixed to work with latest dev-1.5.0 changes * minor fixes --- contracts/interfaces/ISecurityToken.sol | 6 + .../VolumeRestrictionTransferManager.sol | 374 ++ ...olumeRestrictionTransferManagerFactory.sol | 104 + migrations/2_deploy_contracts.js | 1 - package-lock.json | 4466 ++++++++--------- test/w_volume_restriction_transfer_manager.js | 1069 ++++ yarn.lock | 1124 +---- 7 files changed, 3830 insertions(+), 3314 deletions(-) create mode 100644 contracts/modules/TransferManager/VolumeRestrictionTransferManager.sol create mode 100644 contracts/modules/TransferManager/VolumeRestrictionTransferManagerFactory.sol create mode 100644 test/w_volume_restriction_transfer_manager.js diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index 20dcb72c8..e099006bc 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -280,4 +280,10 @@ interface ISecurityToken { * @return bool success */ function transferFromWithData(address _from, address _to, uint256 _value, bytes _data) external returns(bool); + + /** + * @notice Provide the granularity of the token + * @return uint256 + */ + function granularity() external view returns(uint256); } diff --git a/contracts/modules/TransferManager/VolumeRestrictionTransferManager.sol b/contracts/modules/TransferManager/VolumeRestrictionTransferManager.sol new file mode 100644 index 000000000..e79bad1bc --- /dev/null +++ b/contracts/modules/TransferManager/VolumeRestrictionTransferManager.sol @@ -0,0 +1,374 @@ +pragma solidity ^0.4.24; + +import "./ITransferManager.sol"; +import "openzeppelin-solidity/contracts/math/SafeMath.sol"; + + +contract VolumeRestrictionTransferManager is ITransferManager { + + using SafeMath for uint256; + + // permission definition + bytes32 public constant ADMIN = "ADMIN"; + + // a per-user lockup + struct LockUp { + uint lockUpPeriodSeconds; // total period of lockup (seconds) + uint releaseFrequencySeconds; // how often to release a tranche of tokens (seconds) + uint startTime; // when this lockup starts (seconds) + uint totalAmount; // total amount of locked up tokens + uint alreadyWithdrawn; // amount already withdrawn for this lockup + } + + // maps user addresses to an array of lockups for that user + mapping (address => LockUp[]) internal lockUps; + + event AddNewLockUp( + address indexed userAddress, + uint lockUpPeriodSeconds, + uint releaseFrequencySeconds, + uint startTime, + uint totalAmount, + uint indexed addedIndex + ); + + event RemoveLockUp( + address indexed userAddress, + uint lockUpPeriodSeconds, + uint releaseFrequencySeconds, + uint startTime, + uint totalAmount, + uint indexed removedIndex + ); + + event ModifyLockUp( + address indexed userAddress, + uint lockUpPeriodSeconds, + uint releaseFrequencySeconds, + uint startTime, + uint totalAmount, + uint indexed modifiedIndex + ); + + /** + * @notice Constructor + * @param _securityToken Address of the security token + * @param _polyAddress Address of the polytoken + */ + constructor (address _securityToken, address _polyAddress) + public + Module(_securityToken, _polyAddress) + { + } + + + /** @notice Used to verify the transfer transaction and prevent locked up tokens from being transferred + * @param _from Address of the sender + * @param _amount The amount of tokens to transfer + * @param _isTransfer Whether or not this is an actual transfer or just a test to see if the tokens would be transferrable + */ + function verifyTransfer(address _from, address /* _to*/, uint256 _amount, bytes /* _data */, bool _isTransfer) public returns(Result) { + // only attempt to verify the transfer if the token is unpaused, this isn't a mint txn, and there exists a lockup for this user + if (!paused && _from != address(0) && lockUps[_from].length != 0) { + // check if this transfer is valid + return _checkIfValidTransfer(_from, _amount, _isTransfer); + } + return Result.NA; + } + + /** + * @notice Lets the admin create a volume restriction lockup for a given address. + * @param userAddress Address of the user whose tokens should be locked up + * @param lockUpPeriodSeconds Total period of lockup (seconds) + * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) + * @param startTime When this lockup starts (seconds) + * @param totalAmount Total amount of locked up tokens + */ + function addLockUp(address userAddress, uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount) public withPerm(ADMIN) { + + _checkLockUpParams(lockUpPeriodSeconds, releaseFrequencySeconds, totalAmount); + + // if a startTime of 0 is passed in, then start now. + if (startTime == 0) { + startTime = now; + } + + lockUps[userAddress].push(LockUp(lockUpPeriodSeconds, releaseFrequencySeconds, startTime, totalAmount, 0)); + + emit AddNewLockUp( + userAddress, + lockUpPeriodSeconds, + releaseFrequencySeconds, + startTime, + totalAmount, + lockUps[userAddress].length - 1 + ); + } + + /** + * @notice Lets the admin create multiple volume restriction lockups for multiple given addresses. + * @param userAddresses Array of address of the user whose tokens should be locked up + * @param lockUpPeriodsSeconds Array of total periods of lockup (seconds) + * @param releaseFrequenciesSeconds Array of how often to release a tranche of tokens (seconds) + * @param startTimes Array of When this lockup starts (seconds) + * @param totalAmounts Array of total amount of locked up tokens + */ + function addLockUpMulti(address[] userAddresses, uint[] lockUpPeriodsSeconds, uint[] releaseFrequenciesSeconds, uint[] startTimes, uint[] totalAmounts) external withPerm(ADMIN) { + + // make sure input params are sane + require( + userAddresses.length == lockUpPeriodsSeconds.length && + userAddresses.length == releaseFrequenciesSeconds.length && + userAddresses.length == startTimes.length && + userAddresses.length == totalAmounts.length, + "Input array length mis-match" + ); + + for (uint i = 0; i < userAddresses.length; i++) { + addLockUp(userAddresses[i], lockUpPeriodsSeconds[i], releaseFrequenciesSeconds[i], startTimes[i], totalAmounts[i]); + } + + } + + /** + * @notice Lets the admin remove a user's lock up + * @param userAddress Address of the user whose tokens are locked up + * @param lockUpIndex The index of the LockUp to remove for the given userAddress + */ + function removeLockUp(address userAddress, uint lockUpIndex) public withPerm(ADMIN) { + LockUp[] storage userLockUps = lockUps[userAddress]; + require(lockUpIndex < userLockUps.length, "Array out of bounds exception"); + + LockUp memory toRemove = userLockUps[lockUpIndex]; + + emit RemoveLockUp( + userAddress, + toRemove.lockUpPeriodSeconds, + toRemove.releaseFrequencySeconds, + toRemove.startTime, + toRemove.totalAmount, + lockUpIndex + ); + + if (lockUpIndex < userLockUps.length - 1) { + // move the last element in the array into the index that is desired to be removed. + userLockUps[lockUpIndex] = userLockUps[userLockUps.length - 1]; + } + // delete the last element + userLockUps.length--; + } + + /** + * @notice Lets the admin modify a volume restriction lockup for a given address. + * @param userAddress Address of the user whose tokens should be locked up + * @param lockUpIndex The index of the LockUp to edit for the given userAddress + * @param lockUpPeriodSeconds Total period of lockup (seconds) + * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) + * @param startTime When this lockup starts (seconds) + * @param totalAmount Total amount of locked up tokens + */ + function modifyLockUp(address userAddress, uint lockUpIndex, uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount) public withPerm(ADMIN) { + require(lockUpIndex < lockUps[userAddress].length, "Array out of bounds exception"); + + // if a startTime of 0 is passed in, then start now. + if (startTime == 0) { + startTime = now; + } + + _checkLockUpParams(lockUpPeriodSeconds, releaseFrequencySeconds, totalAmount); + + // Get the lockup from the master list and edit it + lockUps[userAddress][lockUpIndex] = LockUp( + lockUpPeriodSeconds, + releaseFrequencySeconds, + startTime, + totalAmount, + lockUps[userAddress][lockUpIndex].alreadyWithdrawn + ); + + emit ModifyLockUp( + userAddress, + lockUpPeriodSeconds, + releaseFrequencySeconds, + startTime, + totalAmount, + lockUpIndex + ); + } + + /** + * @notice Get the length of the lockups array for a specific user address + * @param userAddress Address of the user whose tokens should be locked up + */ + function getLockUpsLength(address userAddress) public view returns (uint) { + return lockUps[userAddress].length; + } + + /** + * @notice Get a specific element in a user's lockups array given the user's address and the element index + * @param userAddress Address of the user whose tokens should be locked up + * @param lockUpIndex The index of the LockUp to edit for the given userAddress + */ + function getLockUp(address userAddress, uint lockUpIndex) public view returns (uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount, uint alreadyWithdrawn) { + require(lockUpIndex < lockUps[userAddress].length, "Array out of bounds exception"); + LockUp storage userLockUp = lockUps[userAddress][lockUpIndex]; + return ( + userLockUp.lockUpPeriodSeconds, + userLockUp.releaseFrequencySeconds, + userLockUp.startTime, + userLockUp.totalAmount, + userLockUp.alreadyWithdrawn + ); + } + + /** + * @notice This function returns the signature of configure function + */ + function getInitFunction() public pure returns (bytes4) { + return bytes4(0); + } + + /** + * @notice Return the permissions flag that are associated with Percentage transfer Manager + */ + function getPermissions() public view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](1); + allPermissions[0] = ADMIN; + return allPermissions; + } + + /** + * @notice Takes a userAddress as input, and returns a uint that represents the number of tokens allowed to be withdrawn right now + * @param userAddress Address of the user whose lock ups should be checked + */ + function _checkIfValidTransfer(address userAddress, uint amount, bool isTransfer) internal returns (Result) { + // get lock up array for this user + LockUp[] storage userLockUps = lockUps[userAddress]; + + // maps the index of userLockUps to the amount allowed in this transfer + uint[] memory allowedAmountPerLockup = new uint[](userLockUps.length); + + uint[3] memory tokenSums = [ + uint256(0), // allowed amount right now + uint256(0), // total locked up, ever + uint256(0) // already withdrawn, ever + ]; + + // loop over the user's lock ups + for (uint i = 0; i < userLockUps.length; i++) { + LockUp storage aLockUp = userLockUps[i]; + + uint allowedAmountForThisLockup = 0; + + // check if lockup has entirely passed + if (now >= aLockUp.startTime.add(aLockUp.lockUpPeriodSeconds)) { + // lockup has passed, or not started yet. allow all. + allowedAmountForThisLockup = aLockUp.totalAmount.sub(aLockUp.alreadyWithdrawn); + } else if (now >= aLockUp.startTime) { + // lockup is active. calculate how many to allow to be withdrawn right now + // calculate how many periods have elapsed already + uint elapsedPeriods = (now.sub(aLockUp.startTime)).div(aLockUp.releaseFrequencySeconds); + // calculate the total number of periods, overall + uint totalPeriods = aLockUp.lockUpPeriodSeconds.div(aLockUp.releaseFrequencySeconds); + // calculate how much should be released per period + uint amountPerPeriod = aLockUp.totalAmount.div(totalPeriods); + // calculate the number of tokens that should be released, + // multiplied by the number of periods that have elapsed already + // and add it to the total tokenSums[0] + allowedAmountForThisLockup = amountPerPeriod.mul(elapsedPeriods).sub(aLockUp.alreadyWithdrawn); + + } + // tokenSums[0] is allowed sum + tokenSums[0] = tokenSums[0].add(allowedAmountForThisLockup); + // tokenSums[1] is total locked up + tokenSums[1] = tokenSums[1].add(aLockUp.totalAmount); + // tokenSums[2] is total already withdrawn + tokenSums[2] = tokenSums[2].add(aLockUp.alreadyWithdrawn); + + allowedAmountPerLockup[i] = allowedAmountForThisLockup; + } + + // tokenSums[0] is allowed sum + if (amount <= tokenSums[0]) { + // transfer is valid and will succeed. + if (!isTransfer) { + // if this isn't a real transfer, don't subtract the withdrawn amounts from the lockups. it's a "read only" txn + return Result.VALID; + } + + // we are going to write the withdrawn balances back to the lockups, so make sure that the person calling this function is the securityToken itself, since its public + require(msg.sender == securityToken, "Sender is not securityToken"); + + // subtract amounts so they are now known to be withdrawen + for (i = 0; i < userLockUps.length; i++) { + aLockUp = userLockUps[i]; + + // tokenSums[0] is allowed sum + if (allowedAmountPerLockup[i] >= tokenSums[0]) { + aLockUp.alreadyWithdrawn = aLockUp.alreadyWithdrawn.add(tokenSums[0]); + // we withdrew the entire tokenSums[0] from the lockup. We are done. + break; + } else { + // we have to split the tokenSums[0] across mutiple lockUps + aLockUp.alreadyWithdrawn = aLockUp.alreadyWithdrawn.add(allowedAmountPerLockup[i]); + // subtract the amount withdrawn from this lockup + tokenSums[0] = tokenSums[0].sub(allowedAmountPerLockup[i]); + } + + } + return Result.VALID; + } + + return _checkIfUnlockedTokenTransferIsPossible(userAddress, amount, tokenSums[1], tokenSums[2]); + } + + function _checkIfUnlockedTokenTransferIsPossible(address userAddress, uint amount, uint totalSum, uint alreadyWithdrawnSum) internal view returns (Result) { + // the amount the user wants to withdraw is greater than their allowed amounts according to the lockups. however, if the user has like, 10 tokens, but only 4 are locked up, we should let the transfer go through for those 6 that aren't locked up + uint currentUserBalance = ISecurityToken(securityToken).balanceOf(userAddress); + uint stillLockedAmount = totalSum.sub(alreadyWithdrawnSum); + if (currentUserBalance >= stillLockedAmount && amount <= currentUserBalance.sub(stillLockedAmount)) { + // the user has more tokens in their balance than are actually locked up. they should be allowed to withdraw the difference + return Result.VALID; + } + return Result.INVALID; + } + + + /** + * @notice Parameter checking function for creating or editing a lockup. This function will cause an exception if any of the parameters are bad. + * @param lockUpPeriodSeconds Total period of lockup (seconds) + * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) + * @param totalAmount Total amount of locked up tokens + */ + function _checkLockUpParams(uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint totalAmount) internal view { + require(lockUpPeriodSeconds != 0, "lockUpPeriodSeconds cannot be zero"); + require(releaseFrequencySeconds != 0, "releaseFrequencySeconds cannot be zero"); + require(totalAmount != 0, "totalAmount cannot be zero"); + + // check that the total amount to be released isn't too granular + require( + totalAmount % ISecurityToken(securityToken).granularity() == 0, + "The total amount to be released is more granular than allowed by the token" + ); + + // check that releaseFrequencySeconds evenly divides lockUpPeriodSeconds + require( + lockUpPeriodSeconds % releaseFrequencySeconds == 0, + "lockUpPeriodSeconds must be evenly divisible by releaseFrequencySeconds" + ); + + // check that totalPeriods evenly divides totalAmount + uint totalPeriods = lockUpPeriodSeconds.div(releaseFrequencySeconds); + require( + totalAmount % totalPeriods == 0, + "The total amount being locked up must be evenly divisible by the number of total periods" + ); + + // make sure the amount to be released per period is not too granular for the token + uint amountPerPeriod = totalAmount.div(totalPeriods); + require( + amountPerPeriod % ISecurityToken(securityToken).granularity() == 0, + "The amount to be released per period is more granular than allowed by the token" + ); + } +} diff --git a/contracts/modules/TransferManager/VolumeRestrictionTransferManagerFactory.sol b/contracts/modules/TransferManager/VolumeRestrictionTransferManagerFactory.sol new file mode 100644 index 000000000..81afdad4c --- /dev/null +++ b/contracts/modules/TransferManager/VolumeRestrictionTransferManagerFactory.sol @@ -0,0 +1,104 @@ +pragma solidity ^0.4.24; + +import "./VolumeRestrictionTransferManager.sol"; +import "../ModuleFactory.sol"; + +/** + * @title Factory for deploying ManualApprovalTransferManager module + */ +contract VolumeRestrictionTransferManagerFactory is ModuleFactory { + + /** + * @notice Constructor + * @param _polyAddress Address of the polytoken + * @param _setupCost Setup cost of the module + * @param _usageCost Usage cost of the module + * @param _subscriptionCost Subscription cost of the module + */ + constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public + ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + { + version = "1.0.0"; + name = "VolumeRestrictionTransferManager"; + title = "Volume Restriction Transfer Manager"; + description = "Manage transfers using lock ups over time"; + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + } + + /** + * @notice used to launch the Module with the help of factory + * @return address Contract address of the Module + */ + function deploy(bytes /* _data */) external returns(address) { + if (setupCost > 0) + require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); + address volumeRestrictionTransferManager = new VolumeRestrictionTransferManager(msg.sender, address(polyToken)); + emit GenerateModuleFromFactory(address(volumeRestrictionTransferManager), getName(), address(this), msg.sender, now); + return address(volumeRestrictionTransferManager); + } + + /** + * @notice Type of the Module factory + * @return uint8 + */ + function getTypes() external view returns(uint8[]) { + uint8[] memory res = new uint8[](1); + res[0] = 2; + return res; + } + + /** + * @notice Get the name of the Module + */ + function getName() public view returns(bytes32) { + return name; + } + + /** + * @notice Get the description of the Module + */ + function getDescription() external view returns(string) { + return description; + } + + /** + * @notice Get the title of the Module + */ + function getTitle() external view returns(string) { + return title; + } + + /** + * @notice Get the version of the Module + */ + function getVersion() external view returns(string) { + return version; + } + + /** + * @notice Get the setup cost of the module + */ + function getSetupCost() external view returns (uint256) { + return setupCost; + } + + /** + * @notice Get the Instructions that helped to used the module + */ + function getInstructions() external view returns(string) { + return "Allows an issuer to set lockup periods for user addresses, with funds distributed over time. Init function takes no parameters."; + } + + /** + * @notice Get the tags related to the module factory + */ + function getTags() external view returns(bytes32[]) { + bytes32[] memory availableTags = new bytes32[](2); + availableTags[0] = "Volume"; + availableTags[1] = "Transfer Restriction"; + return availableTags; + } + + +} diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 7b1feeece..fc242cc9b 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -316,7 +316,6 @@ module.exports = function (deployer, network, accounts) { PercentageTransferManagerFactory: ${PercentageTransferManagerFactory.address} ManualApprovalTransferManagerFactory: ${ManualApprovalTransferManagerFactory.address} - EtherDividendCheckpointFactory: ${EtherDividendCheckpointFactory.address} ERC20DividendCheckpointFactory: ${ERC20DividendCheckpointFactory.address} ----------------------------------------------------------------------------- diff --git a/package-lock.json b/package-lock.json index fc73460ac..8cce7f884 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,14 @@ "integrity": "sha1-JP/ukmQijhw+3WH9MWLWNYeVSTM=", "dev": true, "requires": { - "@soldoc/markdown": "0.1.0", - "chalk": "2.4.1", - "deep-assign": "2.0.0", - "fs-extra": "5.0.0", - "shelljs": "0.8.2", - "solc": "0.4.24", - "valid-url": "1.0.9", - "yargs": "11.0.0" + "@soldoc/markdown": "^0.1.0", + "chalk": "^2.3.1", + "deep-assign": "^2.0.0", + "fs-extra": "^5.0.0", + "shelljs": "^0.8.1", + "solc": "^0.4.19", + "valid-url": "^1.0.9", + "yargs": "^11.0.0" }, "dependencies": { "fs-extra": { @@ -32,9 +32,9 @@ "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } } } @@ -45,37 +45,12 @@ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", "dev": true }, - "abi-decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/abi-decoder/-/abi-decoder-1.2.0.tgz", - "integrity": "sha512-y2OKSEW4gf2838Eavc56vQY9V46zaXkf3Jl1WpTfUBbzAVrXSr4JRZAAWv55Tv9s5WNz1rVgBgz5d2aJIL1QCg==", - "requires": { - "web3": "0.18.4" - }, - "dependencies": { - "bignumber.js": { - "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" - }, - "web3": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", - "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", - "requires": { - "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" - } - } - } - }, "abstract-leveldown": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", "requires": { - "xtend": "4.0.1" + "xtend": "~4.0.0" } }, "accepts": { @@ -83,7 +58,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "2.1.18", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -97,7 +72,7 @@ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", "requires": { - "acorn": "4.0.13" + "acorn": "^4.0.3" }, "dependencies": { "acorn": { @@ -113,7 +88,7 @@ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "dependencies": { "acorn": { @@ -134,10 +109,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "ajv-keywords": { @@ -151,9 +126,9 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" } }, "ambi": { @@ -162,8 +137,8 @@ "integrity": "sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA=", "dev": true, "requires": { - "editions": "1.3.4", - "typechecker": "4.5.0" + "editions": "^1.1.1", + "typechecker": "^4.3.0" }, "dependencies": { "typechecker": { @@ -172,7 +147,7 @@ "integrity": "sha512-bqPE/ck3bVIaXP7gMKTKSHrypT32lpYTpiqzPYeYzdSQnmaGvaGhy7TnN/M/+5R+2rs/kKcp9ZLPRp/Q9Yj+4w==", "dev": true, "requires": { - "editions": "1.3.4" + "editions": "^1.3.4" } } } @@ -199,7 +174,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "any-promise": { @@ -213,8 +188,8 @@ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" } }, "argparse": { @@ -222,7 +197,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "arguments-extended": { @@ -231,8 +206,8 @@ "integrity": "sha1-YQfkkX0OtvCk3WYyD8Fa/HLvSUY=", "dev": true, "requires": { - "extended": "0.0.6", - "is-extended": "0.0.10" + "extended": "~0.0.3", + "is-extended": "~0.0.8" } }, "arr-diff": { @@ -241,7 +216,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "arr-flatten": { @@ -260,9 +235,9 @@ "integrity": "sha1-1xRK50jek8pybxIQCdv/FibRZL0=", "dev": true, "requires": { - "arguments-extended": "0.0.3", - "extended": "0.0.6", - "is-extended": "0.0.10" + "arguments-extended": "~0.0.3", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "array-flatten": { @@ -276,7 +251,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { @@ -313,9 +288,9 @@ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "requires": { - "bn.js": "4.11.6", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "assert": { @@ -351,7 +326,7 @@ "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", "requires": { - "async": "2.6.0" + "async": "^2.4.0" }, "dependencies": { "async": { @@ -359,7 +334,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } } } @@ -394,9 +369,9 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" }, "dependencies": { "ansi-styles": { @@ -409,11 +384,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "supports-color": { @@ -428,25 +403,25 @@ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.1", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.5.1", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.5", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.7" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" } }, "babel-generator": { @@ -454,14 +429,14 @@ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.5", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" }, "dependencies": { "jsesc": { @@ -476,9 +451,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -486,9 +461,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", "requires": { - "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-call-delegate": { @@ -496,10 +471,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-define-map": { @@ -507,10 +482,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.5" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, "babel-helper-explode-assignable-expression": { @@ -518,9 +493,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-explode-class": { @@ -528,10 +503,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", "requires": { - "babel-helper-bindify-decorators": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-function-name": { @@ -539,11 +514,11 @@ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-get-function-arity": { @@ -551,8 +526,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-hoist-variables": { @@ -560,8 +535,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-optimise-call-expression": { @@ -569,8 +544,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-regex": { @@ -578,9 +553,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.5" + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, "babel-helper-remap-async-to-generator": { @@ -588,11 +563,11 @@ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-replace-supers": { @@ -600,12 +575,12 @@ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helpers": { @@ -613,8 +588,8 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-messages": { @@ -622,7 +597,7 @@ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-check-es2015-constants": { @@ -630,7 +605,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-syntax-async-functions": { @@ -678,9 +653,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-generators": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-async-to-generator": { @@ -688,9 +663,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-class-properties": { @@ -698,10 +673,10 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-plugin-syntax-class-properties": "6.13.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-decorators": { @@ -709,11 +684,11 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", "requires": { - "babel-helper-explode-class": "6.24.1", - "babel-plugin-syntax-decorators": "6.13.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -721,7 +696,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -729,7 +704,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -737,11 +712,11 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.5" + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, "babel-plugin-transform-es2015-classes": { @@ -749,15 +724,15 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "requires": { - "babel-helper-define-map": "6.26.0", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -765,8 +740,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-destructuring": { @@ -774,7 +749,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -782,8 +757,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-for-of": { @@ -791,7 +766,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -799,9 +774,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-literals": { @@ -809,7 +784,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -817,9 +792,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -827,10 +802,10 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -838,9 +813,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -848,9 +823,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-object-super": { @@ -858,8 +833,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.26.0" + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -867,12 +842,12 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -880,8 +855,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-spread": { @@ -889,7 +864,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -897,9 +872,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-template-literals": { @@ -907,7 +882,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -915,7 +890,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -923,9 +898,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "regexpu-core": "2.0.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" } }, "babel-plugin-transform-exponentiation-operator": { @@ -933,9 +908,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", - "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-object-rest-spread": { @@ -943,8 +918,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", "requires": { - "babel-plugin-syntax-object-rest-spread": "6.13.0", - "babel-runtime": "6.26.0" + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" } }, "babel-plugin-transform-regenerator": { @@ -952,7 +927,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "requires": { - "regenerator-transform": "0.10.1" + "regenerator-transform": "^0.10.0" } }, "babel-plugin-transform-strict-mode": { @@ -960,8 +935,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-polyfill": { @@ -969,9 +944,9 @@ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "requires": { - "babel-runtime": "6.26.0", - "core-js": "2.5.3", - "regenerator-runtime": "0.10.5" + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" } }, "babel-preset-env": { @@ -979,36 +954,36 @@ "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.11.3", - "invariant": "2.2.3", - "semver": "5.5.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^2.1.2", + "invariant": "^2.2.2", + "semver": "^5.3.0" } }, "babel-preset-es2015": { @@ -1016,30 +991,30 @@ "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" } }, "babel-preset-stage-2": { @@ -1047,10 +1022,10 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", "requires": { - "babel-plugin-syntax-dynamic-import": "6.18.0", - "babel-plugin-transform-class-properties": "6.24.1", - "babel-plugin-transform-decorators": "6.24.1", - "babel-preset-stage-3": "6.24.1" + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" } }, "babel-preset-stage-3": { @@ -1058,11 +1033,11 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", "requires": { - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-generator-functions": "6.24.1", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-object-rest-spread": "6.26.0" + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" } }, "babel-register": { @@ -1070,13 +1045,13 @@ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "requires": { - "babel-core": "6.26.0", - "babel-runtime": "6.26.0", - "core-js": "2.5.3", - "home-or-tmp": "2.0.0", - "lodash": "4.17.5", - "mkdirp": "0.5.1", - "source-map-support": "0.4.18" + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" } }, "babel-runtime": { @@ -1084,8 +1059,8 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.5.3", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { "regenerator-runtime": { @@ -1100,11 +1075,11 @@ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.5" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, "babel-traverse": { @@ -1112,15 +1087,15 @@ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.3", - "lodash": "4.17.5" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" } }, "babel-types": { @@ -1128,10 +1103,10 @@ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.5", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, "babelify": { @@ -1139,8 +1114,8 @@ "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { - "babel-core": "6.26.0", - "object-assign": "4.1.1" + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" } }, "babylon": { @@ -1158,13 +1133,13 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -1172,7 +1147,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -1180,7 +1155,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -1188,7 +1163,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -1196,9 +1171,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -1229,7 +1204,7 @@ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "big.js": { @@ -1257,7 +1232,7 @@ "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "bitcore-lib": { @@ -1266,12 +1241,12 @@ "integrity": "sha512-AeXLWhiivF6CDFzrABZHT4jJrflyylDWTi32o30rF92HW9msfuKpjzrHtFKYGa9w0kNVv5HABQjCB3OEav4PhQ==", "dev": true, "requires": { - "bn.js": "4.11.8", - "bs58": "4.0.1", - "buffer-compare": "1.1.1", - "elliptic": "6.4.0", - "inherits": "2.0.1", - "lodash": "4.17.4" + "bn.js": "=4.11.8", + "bs58": "=4.0.1", + "buffer-compare": "=1.1.1", + "elliptic": "=6.4.0", + "inherits": "=2.0.1", + "lodash": "=4.17.4" }, "dependencies": { "base-x": { @@ -1280,7 +1255,7 @@ "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "bn.js": { @@ -1295,7 +1270,7 @@ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dev": true, "requires": { - "base-x": "3.0.4" + "base-x": "^3.0.2" } }, "inherits": { @@ -1318,8 +1293,8 @@ "integrity": "sha512-sbeP4xwkindLMfIQhVxj6rZSDMwtiKmfc1DqvwpR6Yg+Qo4I4WHO5pvzb12Y04uDh1N3zgD45esHhfH0HHmE4g==", "dev": true, "requires": { - "bitcore-lib": "0.15.0", - "unorm": "1.4.1" + "bitcore-lib": "^0.15.0", + "unorm": "^1.3.3" } }, "bl": { @@ -1327,8 +1302,8 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { - "readable-stream": "2.3.5", - "safe-buffer": "5.1.1" + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" } }, "block-stream": { @@ -1336,7 +1311,7 @@ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "bluebird": { @@ -1355,15 +1330,15 @@ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.2", + "depd": "~1.1.1", + "http-errors": "~1.6.2", "iconv-lite": "0.4.19", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.1", "raw-body": "2.3.2", - "type-is": "1.6.16" + "type-is": "~1.6.15" } }, "boom": { @@ -1371,7 +1346,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "borc": { @@ -1380,10 +1355,10 @@ "integrity": "sha512-2mfipKUXn7yLgwn8D5jZkJqd2ZyzqmYZQX/9d4On33oGNDLwxj5qQMst+nkKyEdaujQRFfrZCId+k8wehQVANg==", "dev": true, "requires": { - "bignumber.js": "6.0.0", - "commander": "2.16.0", - "ieee754": "1.1.10", - "json-text-sequence": "0.1.1" + "bignumber.js": "^6.0.0", + "commander": "^2.15.0", + "ieee754": "^1.1.8", + "json-text-sequence": "^0.1" }, "dependencies": { "bignumber.js": { @@ -1405,7 +1380,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -1415,9 +1390,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "brorand": { @@ -1436,12 +1411,12 @@ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "browserify-cipher": { @@ -1449,9 +1424,9 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "requires": { - "browserify-aes": "1.1.1", - "browserify-des": "1.0.0", - "evp_bytestokey": "1.0.3" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, "browserify-des": { @@ -1459,9 +1434,9 @@ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.3" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1" } }, "browserify-rsa": { @@ -1469,8 +1444,8 @@ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { - "bn.js": "4.11.6", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, "browserify-sha3": { @@ -1478,7 +1453,7 @@ "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", "requires": { - "js-sha3": "0.3.1" + "js-sha3": "^0.3.1" }, "dependencies": { "js-sha3": { @@ -1493,13 +1468,13 @@ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "requires": { - "bn.js": "4.11.6", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "elliptic": "6.4.0", - "inherits": "2.0.3", - "parse-asn1": "5.1.0" + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" } }, "browserify-zlib": { @@ -1507,7 +1482,7 @@ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "requires": { - "pako": "1.0.6" + "pako": "~1.0.5" } }, "browserslist": { @@ -1515,8 +1490,8 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", "requires": { - "caniuse-lite": "1.0.30000819", - "electron-to-chromium": "1.3.40" + "caniuse-lite": "^1.0.30000792", + "electron-to-chromium": "^1.3.30" } }, "bs58": { @@ -1524,7 +1499,7 @@ "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", "requires": { - "base-x": "1.1.0" + "base-x": "^1.1.0" } }, "bs58check": { @@ -1532,8 +1507,8 @@ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", "requires": { - "bs58": "3.1.0", - "create-hash": "1.1.3" + "bs58": "^3.1.0", + "create-hash": "^1.1.0" } }, "bson": { @@ -1548,8 +1523,8 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.10" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, "buffer-compare": { @@ -1599,15 +1574,15 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" }, "dependencies": { "isobject": { @@ -1623,7 +1598,7 @@ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "0.2.0" + "callsites": "^0.2.0" } }, "callsites": { @@ -1643,8 +1618,8 @@ "integrity": "sha1-7B7ARXZkoPCSZDt8ZGxFfVzW9pM=", "dev": true, "requires": { - "bluebird": "3.5.1", - "uuid": "3.2.1" + "bluebird": "^3.4.6", + "uuid": "^3.0.1" } }, "caniuse-lite": { @@ -1662,8 +1637,8 @@ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" } }, "chalk": { @@ -1671,9 +1646,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.4.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "chardet": { @@ -1687,7 +1662,7 @@ "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", "requires": { - "functional-red-black-tree": "1.0.1" + "functional-red-black-tree": "^1.0.1" } }, "chokidar": { @@ -1696,15 +1671,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.1.3", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" } }, "cipher-base": { @@ -1712,8 +1687,8 @@ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "circular-json": { @@ -1727,10 +1702,10 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -1738,7 +1713,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "isobject": { @@ -1754,12 +1729,12 @@ "integrity": "sha1-OlrnT9drYmevZm5p4q+70B3vNNE=", "dev": true, "requires": { - "ansi-regex": "2.1.1", - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", - "memoizee": "0.4.12", - "timers-ext": "0.1.3" + "ansi-regex": "^2.1.1", + "d": "1", + "es5-ext": "^0.10.12", + "es6-iterator": "2", + "memoizee": "^0.4.3", + "timers-ext": "0.1" } }, "cli-cursor": { @@ -1768,7 +1743,7 @@ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "2.0.0" + "restore-cursor": "^2.0.0" } }, "cli-width": { @@ -1783,9 +1758,9 @@ "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", "dev": true, "requires": { - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "wrap-ansi": "2.1.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -1800,7 +1775,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -1820,8 +1795,8 @@ "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", "requires": { - "bs58": "2.0.1", - "create-hash": "1.1.3" + "bs58": "^2.0.1", + "create-hash": "^1.1.1" }, "dependencies": { "bs58": { @@ -1836,8 +1811,8 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -1845,7 +1820,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "requires": { - "color-name": "1.1.3" + "color-name": "^1.1.1" } }, "color-name": { @@ -1864,7 +1839,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -1894,10 +1869,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "1.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.5", - "typedarray": "0.0.6" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "console-browserify": { @@ -1905,7 +1880,7 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "requires": { - "date-now": "0.1.4" + "date-now": "^0.1.4" } }, "constants-browserify": { @@ -1964,8 +1939,8 @@ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", "requires": { - "object-assign": "4.1.1", - "vary": "1.1.2" + "object-assign": "^4", + "vary": "^1" } }, "coveralls": { @@ -1973,11 +1948,11 @@ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", "requires": { - "js-yaml": "3.11.0", - "lcov-parse": "0.0.10", - "log-driver": "1.2.7", - "minimist": "1.2.0", - "request": "2.85.0" + "js-yaml": "^3.6.1", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.5", + "minimist": "^1.2.0", + "request": "^2.79.0" }, "dependencies": { "minimist": { @@ -1992,8 +1967,8 @@ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", "requires": { - "bn.js": "4.11.6", - "elliptic": "6.4.0" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, "create-hash": { @@ -2001,10 +1976,10 @@ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "sha.js": "2.4.10" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "sha.js": "^2.4.0" } }, "create-hmac": { @@ -2012,12 +1987,12 @@ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "cron-parser": { @@ -2026,8 +2001,8 @@ "integrity": "sha512-gzmXu16/prizIbKPPKJo+WgBpV7k8Rxxu9FgaANW+vx5DebCXavfRqbROjKkr9ETvVPqs+IO+NXj4GG/eLf8zQ==", "dev": true, "requires": { - "is-nan": "1.2.1", - "moment-timezone": "0.5.21" + "is-nan": "^1.2.1", + "moment-timezone": "^0.5.0" } }, "cryptiles": { @@ -2035,7 +2010,7 @@ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "requires": { - "boom": "5.2.0" + "boom": "5.x.x" }, "dependencies": { "boom": { @@ -2043,7 +2018,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } } } @@ -2053,17 +2028,17 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "requires": { - "browserify-cipher": "1.0.0", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", - "inherits": "2.0.3", - "pbkdf2": "3.0.14", - "public-encrypt": "4.0.0", - "randombytes": "2.0.6", - "randomfill": "1.0.4" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, "crypto-js": { @@ -2094,7 +2069,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "0.10.39" + "es5-ext": "^0.10.9" } }, "dashdash": { @@ -2102,7 +2077,7 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "date-extended": { @@ -2111,9 +2086,9 @@ "integrity": "sha1-I4AtV90b94GIE/4MMuhRqG2iZ8k=", "dev": true, "requires": { - "array-extended": "0.0.11", - "extended": "0.0.6", - "is-extended": "0.0.10" + "array-extended": "~0.0.3", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "date-now": { @@ -2121,12 +2096,6 @@ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, "death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", @@ -2162,14 +2131,14 @@ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", "requires": { - "decompress-tar": "4.1.1", - "decompress-tarbz2": "4.1.1", - "decompress-targz": "4.1.1", - "decompress-unzip": "4.0.1", - "graceful-fs": "4.1.11", - "make-dir": "1.2.0", - "pify": "2.3.0", - "strip-dirs": "2.1.0" + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" }, "dependencies": { "pify": { @@ -2184,7 +2153,7 @@ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "requires": { - "mimic-response": "1.0.0" + "mimic-response": "^1.0.0" } }, "decompress-tar": { @@ -2192,9 +2161,9 @@ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "requires": { - "file-type": "5.2.0", - "is-stream": "1.1.0", - "tar-stream": "1.5.5" + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" } }, "decompress-tarbz2": { @@ -2202,11 +2171,11 @@ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "requires": { - "decompress-tar": "4.1.1", - "file-type": "6.2.0", - "is-stream": "1.1.0", - "seek-bzip": "1.0.5", - "unbzip2-stream": "1.2.5" + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" }, "dependencies": { "file-type": { @@ -2221,9 +2190,9 @@ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "requires": { - "decompress-tar": "4.1.1", - "file-type": "5.2.0", - "is-stream": "1.1.0" + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" } }, "decompress-unzip": { @@ -2231,10 +2200,10 @@ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", "requires": { - "file-type": "3.9.0", - "get-stream": "2.3.1", - "pify": "2.3.0", - "yauzl": "2.9.1" + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" }, "dependencies": { "file-type": { @@ -2247,8 +2216,8 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "requires": { - "object-assign": "4.1.1", - "pinkie-promise": "2.0.1" + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -2264,7 +2233,7 @@ "integrity": "sha1-6+BrHwfwja5ZdiDj3RYi83GhxXI=", "dev": true, "requires": { - "is-obj": "1.0.1" + "is-obj": "^1.0.0" } }, "deep-equal": { @@ -2283,7 +2252,7 @@ "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", "requires": { - "abstract-leveldown": "2.6.3" + "abstract-leveldown": "~2.6.0" } }, "define-properties": { @@ -2291,8 +2260,8 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.11" + "foreach": "^2.0.5", + "object-keys": "^1.0.8" }, "dependencies": { "object-keys": { @@ -2307,8 +2276,8 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -2316,7 +2285,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2324,7 +2293,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2332,9 +2301,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -2360,13 +2329,13 @@ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.1", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.2.8" + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" }, "dependencies": { "globby": { @@ -2375,12 +2344,12 @@ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -2412,8 +2381,8 @@ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "destroy": { @@ -2426,7 +2395,7 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "diff": { @@ -2440,9 +2409,9 @@ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "requires": { - "bn.js": "4.11.6", - "miller-rabin": "4.0.1", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, "doctrine": { @@ -2451,7 +2420,7 @@ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "2.0.2" + "esutils": "^2.0.2" } }, "dom-walk": { @@ -2469,9 +2438,9 @@ "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", "requires": { - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6" + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" } }, "duplexer3": { @@ -2485,7 +2454,7 @@ "integrity": "sha1-Rm98qhBwj2EFCeMsgHqv5X/BIr8=", "dev": true, "requires": { - "typechecker": "2.1.0" + "typechecker": "^2.0.8" } }, "ecc-jsbn": { @@ -2494,7 +2463,7 @@ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "editions": { @@ -2518,13 +2487,13 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "requires": { - "bn.js": "4.11.6", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, "emojis-list": { @@ -2542,7 +2511,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "0.4.19" + "iconv-lite": "~0.4.13" } }, "end-of-stream": { @@ -2550,7 +2519,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { - "once": "1.4.0" + "once": "^1.4.0" } }, "errno": { @@ -2558,7 +2527,7 @@ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "requires": { - "prr": "1.0.1" + "prr": "~1.0.1" } }, "error-ex": { @@ -2566,7 +2535,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "es-abstract": { @@ -2574,11 +2543,11 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" } }, "es-to-primitive": { @@ -2586,9 +2555,9 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" } }, "es5-ext": { @@ -2596,8 +2565,8 @@ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.39.tgz", "integrity": "sha512-AlaXZhPHl0po/uxMx1tyrlt1O86M6D5iVaDH8UgLfgek4kXTX6vzsRfJQWC2Ku+aG8pkw1XWzh9eTkwfVrsD5g==", "requires": { - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1" } }, "es6-iterator": { @@ -2605,9 +2574,9 @@ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, "es6-map": { @@ -2615,12 +2584,12 @@ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" } }, "es6-set": { @@ -2628,11 +2597,11 @@ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "event-emitter": "~0.3.5" } }, "es6-symbol": { @@ -2640,8 +2609,8 @@ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39" + "d": "1", + "es5-ext": "~0.10.14" } }, "es6-weak-map": { @@ -2649,10 +2618,10 @@ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" } }, "escape-html": { @@ -2671,11 +2640,11 @@ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { - "esprima": "2.7.3", - "estraverse": "1.9.3", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.2.0" + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" }, "dependencies": { "esprima": { @@ -2697,7 +2666,7 @@ "dev": true, "optional": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -2707,10 +2676,10 @@ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint": { @@ -2719,44 +2688,44 @@ "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { - "ajv": "5.5.2", - "babel-code-frame": "6.26.0", - "chalk": "2.3.2", - "concat-stream": "1.6.2", - "cross-spawn": "5.1.0", - "debug": "3.1.0", - "doctrine": "2.1.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0", - "espree": "3.5.4", - "esquery": "1.0.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "11.4.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "3.3.0", - "is-resolvable": "1.1.0", - "js-yaml": "3.11.0", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.5", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "regexpp": "1.1.0", - "require-uncached": "1.0.3", - "semver": "5.5.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", "table": "4.0.2", - "text-table": "0.2.0" + "text-table": "~0.2.0" }, "dependencies": { "ansi-regex": { @@ -2771,7 +2740,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -2780,9 +2749,9 @@ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "cross-spawn": { @@ -2791,9 +2760,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.2", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "debug": { @@ -2817,20 +2786,20 @@ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.3.2", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.1.0", - "figures": "2.0.0", - "lodash": "4.17.5", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" } }, "strip-ansi": { @@ -2839,7 +2808,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "supports-color": { @@ -2848,7 +2817,7 @@ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -2865,8 +2834,8 @@ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", "dev": true, "requires": { - "debug": "2.6.9", - "resolve": "1.5.0" + "debug": "^2.6.9", + "resolve": "^1.5.0" } }, "eslint-module-utils": { @@ -2875,8 +2844,8 @@ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", "dev": true, "requires": { - "debug": "2.6.9", - "pkg-dir": "1.0.0" + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" } }, "eslint-plugin-import": { @@ -2885,16 +2854,16 @@ "integrity": "sha1-+gkIPVp1KI35xsfQn+EiVZhWVec=", "dev": true, "requires": { - "builtin-modules": "1.1.1", - "contains-path": "0.1.0", - "debug": "2.6.9", + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.2", - "eslint-module-utils": "2.2.0", - "has": "1.0.1", - "lodash": "4.17.5", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0" + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.2.0", + "has": "^1.0.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" }, "dependencies": { "doctrine": { @@ -2903,8 +2872,8 @@ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "esutils": "^2.0.2", + "isarray": "^1.0.0" } }, "load-json-file": { @@ -2913,10 +2882,10 @@ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, "parse-json": { @@ -2925,7 +2894,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-type": { @@ -2934,7 +2903,7 @@ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { - "pify": "2.3.0" + "pify": "^2.0.0" } }, "pify": { @@ -2949,9 +2918,9 @@ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "read-pkg-up": { @@ -2960,8 +2929,8 @@ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "strip-bom": { @@ -2978,10 +2947,10 @@ "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", "dev": true, "requires": { - "ignore": "3.3.7", - "minimatch": "3.0.4", - "resolve": "1.5.0", - "semver": "5.5.0" + "ignore": "^3.3.6", + "minimatch": "^3.0.4", + "resolve": "^1.3.3", + "semver": "^5.4.1" } }, "eslint-plugin-promise": { @@ -3002,8 +2971,8 @@ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint-visitor-keys": { @@ -3018,8 +2987,8 @@ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "acorn": "5.5.3", - "acorn-jsx": "3.0.1" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, "esprima": { @@ -3033,7 +3002,7 @@ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { @@ -3041,7 +3010,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.1.0" } }, "estraverse": { @@ -3065,13 +3034,13 @@ "integrity": "sha512-yrNyBIBKC7WfUjrXSG/CZVy0gW2aF8+MnjnrkOxkZOR+BAtL6JgYOnzVnrU8KE6mKJETlA/1dYMygvLXWyJGGw==", "requires": { "async-eventemitter": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "eth-query": "2.1.2", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "ethjs-util": "0.1.4", - "json-rpc-engine": "3.6.1", - "pify": "2.3.0", - "tape": "4.9.0" + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" }, "dependencies": { "async": { @@ -3079,13 +3048,14 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "async-eventemitter": { "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", + "from": "async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", "requires": { - "async": "2.6.0" + "async": "^2.4.0" } }, "ethereumjs-util": { @@ -3093,13 +3063,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "pify": { @@ -3114,13 +3084,13 @@ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", "requires": { - "bn.js": "4.11.6", - "elliptic": "6.4.0", - "keccakjs": "0.2.1", - "nano-json-stream-parser": "0.1.2", - "servify": "0.1.12", - "ws": "3.3.3", - "xhr-request-promise": "0.1.2" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "keccakjs": "^0.2.1", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" } }, "eth-lightwallet": { @@ -3129,21 +3099,22 @@ "integrity": "sha512-79vVCETy+4l1b6wuOWwjqPW3Bom5ZK46BgkUNwaXhiMG1rrMRHjpjYEWMqH0JHeCzOzB4HBIFz7eK1/4s6w5nA==", "dev": true, "requires": { - "bitcore-lib": "0.15.0", - "bitcore-mnemonic": "1.5.0", - "buffer": "4.9.1", - "crypto-js": "3.1.8", - "elliptic": "3.1.0", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.2.0", - "rlp": "2.0.0", - "scrypt-async": "1.3.1", + "bitcore-lib": "^0.15.0", + "bitcore-mnemonic": "^1.5.0", + "buffer": "^4.9.0", + "crypto-js": "^3.1.5", + "elliptic": "^3.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.1", + "rlp": "^2.0.0", + "scrypt-async": "^1.2.0", "tweetnacl": "0.13.2", "web3": "0.20.2" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "dev": true }, "bn.js": { @@ -3158,9 +3129,9 @@ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.10", - "isarray": "1.0.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "elliptic": { @@ -3169,10 +3140,10 @@ "integrity": "sha1-whaC73YnabVqdCAWCRBdoR1fYMw=", "dev": true, "requires": { - "bn.js": "2.2.0", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "inherits": "2.0.3" + "bn.js": "^2.0.3", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" } }, "ethereumjs-util": { @@ -3181,13 +3152,13 @@ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "4.11.8", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" }, "dependencies": { "bn.js": { @@ -3211,10 +3182,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -3224,8 +3195,8 @@ "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", "requires": { - "json-rpc-random-id": "1.0.1", - "xtend": "4.0.1" + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" } }, "eth-sig-util": { @@ -3234,14 +3205,15 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "ethereumjs-util": "5.1.5" + "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", + "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", "requires": { - "bn.js": "4.11.6", - "ethereumjs-util": "5.1.5" + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" } }, "ethereumjs-util": { @@ -3249,13 +3221,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3266,31 +3238,31 @@ "integrity": "sha512-yDTivI85618BoLI71yNRzW6iVcVN2rjnviCIzs0QOCOENj4XpYQhMDGhdqDi8XWDdzTd0Ja/Canuuh3vfE2IcA==", "dev": true, "requires": { - "async": "2.6.1", - "borc": "2.0.3", + "async": "^2.4.1", + "borc": "^2.0.2", "caminte": "0.3.7", - "colors": "1.2.1", - "compare-versions": "3.3.0", - "crypto-random-string": "1.0.0", - "eth-lightwallet": "3.0.1", + "colors": "^1.1.2", + "compare-versions": "^3.0.1", + "crypto-random-string": "^1.0.0", + "eth-lightwallet": "^3.0.1", "ethereumjs-abi": "0.6.4", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.2.0", - "i18n": "0.8.3", - "moment": "2.22.2", - "multihashes": "0.4.13", - "node-async-loop": "1.2.2", - "node-cache": "4.2.0", - "node-schedule": "1.3.0", + "ethereumjs-tx": "^1.3.1", + "ethereumjs-util": "^5.2.0", + "i18n": "^0.8.3", + "moment": "^2.22.2", + "multihashes": "^0.4.5", + "node-async-loop": "^1.2.2", + "node-cache": "^4.1.1", + "node-schedule": "^1.2.3", "pragma-singleton": "1.0.3", - "request": "2.85.0", - "semver": "5.5.0", - "stdio": "0.2.7", - "tingodb": "0.6.1", - "underscore": "1.9.1", - "utf8": "2.1.2", + "request": "^2.81.0", + "semver": "^5.5.0", + "stdio": "^0.2.7", + "tingodb": "^0.6.1", + "underscore": "^1.8.3", + "utf8": "^2.1.2", "web3": "0.19.1", - "winston": "2.4.3" + "winston": "^2.3.1" }, "dependencies": { "async": { @@ -3299,7 +3271,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "4.17.10" + "lodash": "^4.17.10" } }, "bignumber.js": { @@ -3314,8 +3286,8 @@ "integrity": "sha1-m6G7BWSS0AwnJ59uzNTVgnWRLBo=", "dev": true, "requires": { - "bn.js": "4.11.6", - "ethereumjs-util": "4.5.0" + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" }, "dependencies": { "ethereumjs-util": { @@ -3324,11 +3296,11 @@ "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "dev": true, "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "keccakjs": "0.2.1", - "rlp": "2.0.0", - "secp256k1": "3.5.0" + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "keccakjs": "^0.2.0", + "rlp": "^2.0.0", + "secp256k1": "^3.0.1" } } } @@ -3339,13 +3311,13 @@ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "lodash": { @@ -3372,11 +3344,11 @@ "integrity": "sha1-52PVsRB8S8JKvU+MvuG6Nlnm6zE=", "dev": true, "requires": { - "bignumber.js": "4.1.0", - "crypto-js": "3.1.8", - "utf8": "2.1.2", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "bignumber.js": "^4.0.2", + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -3392,8 +3364,8 @@ "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", "dev": true, "requires": { - "bn.js": "4.11.6", - "ethereumjs-util": "4.5.0" + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" } }, "ethereumjs-account": { @@ -3401,8 +3373,8 @@ "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.4.tgz", "integrity": "sha1-+MMCMby3B/RRTYoFLB+doQNiTUc=", "requires": { - "ethereumjs-util": "4.5.0", - "rlp": "2.0.0" + "ethereumjs-util": "^4.0.1", + "rlp": "^2.0.0" } }, "ethereumjs-block": { @@ -3410,11 +3382,11 @@ "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", "requires": { - "async": "2.6.0", + "async": "^2.0.1", "ethereum-common": "0.2.0", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "merkle-patricia-tree": "2.3.1" + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" }, "dependencies": { "async": { @@ -3422,7 +3394,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "ethereumjs-util": { @@ -3430,13 +3402,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3446,7 +3418,7 @@ "resolved": "https://registry.npmjs.org/ethereumjs-testrpc/-/ethereumjs-testrpc-6.0.3.tgz", "integrity": "sha512-lAxxsxDKK69Wuwqym2K49VpXtBvLEsXr1sryNG4AkvL5DomMdeCBbu3D87UEevKenLHBiT8GTjARwN6Yj039gA==", "requires": { - "webpack": "3.11.0" + "webpack": "^3.0.0" } }, "ethereumjs-testrpc-sc": { @@ -3455,7 +3427,7 @@ "integrity": "sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg==", "dev": true, "requires": { - "source-map-support": "0.5.9" + "source-map-support": "^0.5.3" }, "dependencies": { "source-map": { @@ -3470,8 +3442,8 @@ "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "buffer-from": "1.0.0", - "source-map": "0.6.1" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } } } @@ -3481,8 +3453,8 @@ "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz", "integrity": "sha512-kOgUd5jC+0tgV7t52UDECMMz9Uf+Lro+6fSpCvzWemtXfMEcwI3EOxf5mVPMRbTFkMMhuERokNNVF3jItAjidg==", "requires": { - "ethereum-common": "0.0.18", - "ethereumjs-util": "5.1.5" + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" }, "dependencies": { "ethereum-common": { @@ -3495,13 +3467,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3511,11 +3483,11 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "keccakjs": "0.2.1", - "rlp": "2.0.0", - "secp256k1": "3.5.0" + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "keccakjs": "^0.2.0", + "rlp": "^2.0.0", + "secp256k1": "^3.0.1" } }, "ethereumjs-vm": { @@ -3523,17 +3495,17 @@ "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.3.tgz", "integrity": "sha512-yIWJqTEcrF9vJTCvNMxacRkAx6zIZTOW0SmSA+hSFiU1x8JyVZDi9o5udwsRVECT5RkPgQzm62kpL6Pf4qemsw==", "requires": { - "async": "2.6.0", - "async-eventemitter": "0.2.4", + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", "ethereum-common": "0.2.0", - "ethereumjs-account": "2.0.4", - "ethereumjs-block": "1.7.1", - "ethereumjs-util": "5.1.5", - "fake-merkle-patricia-tree": "1.0.1", - "functional-red-black-tree": "1.0.1", - "merkle-patricia-tree": "2.3.1", - "rustbn.js": "0.1.2", - "safe-buffer": "5.1.1" + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~1.7.0", + "ethereumjs-util": "^5.1.3", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.1.2", + "rustbn.js": "~0.1.1", + "safe-buffer": "^5.1.1" }, "dependencies": { "async": { @@ -3541,7 +3513,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "ethereumjs-util": { @@ -3549,13 +3521,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3565,13 +3537,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", "requires": { - "aes-js": "0.2.4", - "bs58check": "1.3.4", - "ethereumjs-util": "4.5.0", - "hdkey": "0.7.1", - "scrypt.js": "0.2.0", - "utf8": "2.1.1", - "uuid": "2.0.3" + "aes-js": "^0.2.3", + "bs58check": "^1.0.8", + "ethereumjs-util": "^4.4.0", + "hdkey": "^0.7.0", + "scrypt.js": "^0.2.0", + "utf8": "^2.1.1", + "uuid": "^2.0.1" }, "dependencies": { "uuid": { @@ -3587,9 +3559,9 @@ "integrity": "sha512-d/tiMUavaeaY2GFqjpgfPzT46cEc0cilP3hnlTXR3LR/HR5Qrhv4PfdgW3gxBlR5aBTtUeM/lo8z8ph3JdtFhQ==", "requires": { "aes-js": "3.0.0", - "bn.js": "4.11.6", + "bn.js": "^4.4.0", "elliptic": "6.3.3", - "hash.js": "1.1.3", + "hash.js": "^1.0.0", "inherits": "2.0.1", "js-sha3": "0.5.7", "scrypt-js": "2.0.3", @@ -3608,10 +3580,10 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", "requires": { - "bn.js": "4.11.6", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "inherits": "2.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" } }, "inherits": { @@ -3659,8 +3631,8 @@ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39" + "d": "1", + "es5-ext": "~0.10.14" } }, "eventemitter3": { @@ -3678,8 +3650,8 @@ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "requires": { - "md5.js": "1.3.4", - "safe-buffer": "5.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, "execa": { @@ -3687,13 +3659,13 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" }, "dependencies": { "cross-spawn": { @@ -3701,9 +3673,9 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "requires": { - "lru-cache": "4.1.2", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } } } @@ -3714,7 +3686,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "expand-range": { @@ -3723,7 +3695,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.3" + "fill-range": "^2.1.0" } }, "express": { @@ -3731,36 +3703,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.2", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.3", + "proxy-addr": "~2.0.3", "qs": "6.5.1", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.1", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" }, "dependencies": { "setprototypeof": { @@ -3780,8 +3752,8 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -3789,7 +3761,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -3800,7 +3772,7 @@ "integrity": "sha1-f7i/e52uOXWG5IVwrP1kLHjlBmk=", "dev": true, "requires": { - "extender": "0.0.10" + "extender": "~0.0.5" } }, "extender": { @@ -3809,7 +3781,7 @@ "integrity": "sha1-WJwHSCvmGhRgttgfnCSqZ+jzJM0=", "dev": true, "requires": { - "declare.js": "0.0.8" + "declare.js": "~0.0.4" } }, "extendr": { @@ -3818,7 +3790,7 @@ "integrity": "sha1-MBqgu+pWX00tyPVw8qImEahSe1Y=", "dev": true, "requires": { - "typechecker": "2.0.8" + "typechecker": "~2.0.1" }, "dependencies": { "typechecker": { @@ -3835,9 +3807,9 @@ "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", "dev": true, "requires": { - "chardet": "0.4.2", - "iconv-lite": "0.4.19", - "tmp": "0.0.33" + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" } }, "extglob": { @@ -3846,7 +3818,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "extract-opts": { @@ -3855,7 +3827,7 @@ "integrity": "sha1-H6KOunNSxttID4hc63GkaBC+bX0=", "dev": true, "requires": { - "typechecker": "2.0.8" + "typechecker": "~2.0.1" }, "dependencies": { "typechecker": { @@ -3882,7 +3854,7 @@ "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", "requires": { - "checkpoint-store": "1.1.0" + "checkpoint-store": "^1.1.0" } }, "fast-csv": { @@ -3919,13 +3891,13 @@ "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", "dev": true, "requires": { - "core-js": "1.2.7", - "isomorphic-fetch": "2.2.1", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "promise": "7.3.1", - "setimmediate": "1.0.5", - "ua-parser-js": "0.7.18" + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" }, "dependencies": { "core-js": { @@ -3941,7 +3913,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "requires": { - "pend": "1.2.0" + "pend": "~1.2.0" } }, "fetch-ponyfill": { @@ -3949,7 +3921,7 @@ "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", "requires": { - "node-fetch": "1.7.3" + "node-fetch": "~1.7.1" } }, "figures": { @@ -3958,7 +3930,7 @@ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5" + "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { @@ -3967,8 +3939,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "file-type": { @@ -3988,11 +3960,11 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "finalhandler": { @@ -4001,12 +3973,12 @@ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, "find-up": { @@ -4014,7 +3986,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "2.0.0" + "locate-path": "^2.0.0" } }, "flat-cache": { @@ -4023,10 +3995,10 @@ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, "for-each": { @@ -4034,7 +4006,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", "requires": { - "is-function": "1.0.1" + "is-function": "~1.0.0" } }, "for-in": { @@ -4048,7 +4020,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "foreach": { @@ -4066,9 +4038,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "asynckit": "0.4.0", + "asynckit": "^0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.18" + "mime-types": "^2.1.12" } }, "forwarded": { @@ -4081,7 +4053,7 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -4095,9 +4067,9 @@ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, "fs-promise": { @@ -4105,10 +4077,10 @@ "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", "requires": { - "any-promise": "1.3.0", - "fs-extra": "2.1.2", - "mz": "2.7.0", - "thenify-all": "1.6.0" + "any-promise": "^1.3.0", + "fs-extra": "^2.0.0", + "mz": "^2.6.0", + "thenify-all": "^1.6.0" }, "dependencies": { "fs-extra": { @@ -4116,8 +4088,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" } }, "jsonfile": { @@ -4125,7 +4097,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } } } @@ -4141,8 +4113,8 @@ "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", "optional": true, "requires": { - "nan": "2.9.2", - "node-pre-gyp": "0.6.39" + "nan": "^2.3.0", + "node-pre-gyp": "^0.6.39" }, "dependencies": { "abbrev": { @@ -4155,8 +4127,8 @@ "bundled": true, "optional": true, "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, "ansi-regex": { @@ -4173,8 +4145,8 @@ "bundled": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "asn1": { @@ -4211,28 +4183,28 @@ "bundled": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "block-stream": { "version": "0.0.9", "bundled": true, "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "boom": { "version": "2.10.1", "bundled": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "brace-expansion": { "version": "1.1.7", "bundled": true, "requires": { - "balanced-match": "0.4.2", + "balanced-match": "^0.4.1", "concat-map": "0.0.1" } }, @@ -4258,7 +4230,7 @@ "version": "1.0.5", "bundled": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "concat-map": { @@ -4277,7 +4249,7 @@ "version": "2.0.5", "bundled": true, "requires": { - "boom": "2.10.1" + "boom": "2.x.x" } }, "dashdash": { @@ -4285,7 +4257,7 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -4327,7 +4299,7 @@ "bundled": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "extend": { @@ -4349,9 +4321,9 @@ "bundled": true, "optional": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" } }, "fs.realpath": { @@ -4362,10 +4334,10 @@ "version": "1.0.11", "bundled": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "fstream-ignore": { @@ -4373,9 +4345,9 @@ "bundled": true, "optional": true, "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" } }, "gauge": { @@ -4383,14 +4355,14 @@ "bundled": true, "optional": true, "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "getpass": { @@ -4398,7 +4370,7 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -4412,12 +4384,12 @@ "version": "7.1.2", "bundled": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "graceful-fs": { @@ -4434,8 +4406,8 @@ "bundled": true, "optional": true, "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "^4.9.1", + "har-schema": "^1.0.5" } }, "has-unicode": { @@ -4447,10 +4419,10 @@ "version": "3.1.3", "bundled": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "hoek": { @@ -4462,17 +4434,17 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { "version": "1.0.6", "bundled": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -4488,7 +4460,7 @@ "version": "1.0.0", "bundled": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-typedarray": { @@ -4510,7 +4482,7 @@ "bundled": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "jsbn": { @@ -4528,7 +4500,7 @@ "bundled": true, "optional": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stringify-safe": { @@ -4567,14 +4539,14 @@ "version": "2.1.15", "bundled": true, "requires": { - "mime-db": "1.27.0" + "mime-db": "~1.27.0" } }, "minimatch": { "version": "3.0.4", "bundled": true, "requires": { - "brace-expansion": "1.1.7" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -4598,17 +4570,17 @@ "bundled": true, "optional": true, "requires": { - "detect-libc": "1.0.2", + "detect-libc": "^1.0.2", "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.0.2", + "rc": "^1.1.7", "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^2.2.1", + "tar-pack": "^3.4.0" } }, "nopt": { @@ -4616,8 +4588,8 @@ "bundled": true, "optional": true, "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npmlog": { @@ -4625,10 +4597,10 @@ "bundled": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -4649,7 +4621,7 @@ "version": "1.4.0", "bundled": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -4667,8 +4639,8 @@ "bundled": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -4699,10 +4671,10 @@ "bundled": true, "optional": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -4716,13 +4688,13 @@ "version": "2.2.9", "bundled": true, "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" } }, "request": { @@ -4730,35 +4702,35 @@ "bundled": true, "optional": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" } }, "rimraf": { "version": "2.6.1", "bundled": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -4784,7 +4756,7 @@ "version": "1.0.9", "bundled": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "sshpk": { @@ -4792,15 +4764,15 @@ "bundled": true, "optional": true, "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jodid25519": "^1.0.0", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" }, "dependencies": { "assert-plus": { @@ -4814,16 +4786,16 @@ "version": "1.0.2", "bundled": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.0.1", "bundled": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "stringstream": { @@ -4835,7 +4807,7 @@ "version": "3.0.1", "bundled": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -4847,9 +4819,9 @@ "version": "2.2.1", "bundled": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-pack": { @@ -4857,14 +4829,14 @@ "bundled": true, "optional": true, "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" + "debug": "^2.2.0", + "fstream": "^1.0.10", + "fstream-ignore": "^1.0.5", + "once": "^1.3.3", + "readable-stream": "^2.1.4", + "rimraf": "^2.5.1", + "tar": "^2.2.1", + "uid-number": "^0.0.6" } }, "tough-cookie": { @@ -4872,7 +4844,7 @@ "bundled": true, "optional": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { @@ -4880,7 +4852,7 @@ "bundled": true, "optional": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -4915,7 +4887,7 @@ "bundled": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { @@ -4929,10 +4901,10 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.2.8" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "function-bind": { @@ -4951,7 +4923,7 @@ "integrity": "sha512-yXzteu4SIgUL31mnpm9j+x6dpHUw0p/nsRVkcySKq0w+1vDxH9jMErP1QhZAJuTVE6ni4nfvGSNkaQx5cD3jfg==", "dev": true, "requires": { - "source-map-support": "0.5.9" + "source-map-support": "^0.5.3" }, "dependencies": { "source-map": { @@ -4966,8 +4938,8 @@ "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "buffer-from": "1.0.0", - "source-map": "0.6.1" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } } } @@ -4992,7 +4964,7 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -5000,12 +4972,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-base": { @@ -5014,8 +4986,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" } }, "glob-parent": { @@ -5024,7 +4996,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "global": { @@ -5032,8 +5004,8 @@ "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", "requires": { - "min-document": "2.19.0", - "process": "0.5.2" + "min-document": "^2.19.0", + "process": "~0.5.1" } }, "globals": { @@ -5051,25 +5023,16 @@ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, - "grouped-queue": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/grouped-queue/-/grouped-queue-0.3.3.tgz", - "integrity": "sha1-wWfSpTGcWg4JZO9qJbfC34mWyFw=", - "dev": true, - "requires": { - "lodash": "4.17.5" - } - }, "handlebars": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" }, "dependencies": { "source-map": { @@ -5078,7 +5041,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -5093,8 +5056,8 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "ajv": "^5.1.0", + "har-schema": "^2.0.0" } }, "has": { @@ -5102,7 +5065,7 @@ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.0.2" } }, "has-ansi": { @@ -5110,7 +5073,7 @@ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -5128,7 +5091,7 @@ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", "requires": { - "has-symbol-support-x": "1.4.2" + "has-symbol-support-x": "^1.4.1" } }, "has-value": { @@ -5136,9 +5099,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -5153,8 +5116,8 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "is-number": { @@ -5162,7 +5125,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -5170,7 +5133,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5180,7 +5143,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5190,7 +5153,7 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", "requires": { - "inherits": "2.0.3" + "inherits": "^2.0.1" } }, "hash.js": { @@ -5198,8 +5161,8 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" } }, "hawk": { @@ -5207,10 +5170,10 @@ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.1", - "sntp": "2.1.0" + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" } }, "hdkey": { @@ -5218,8 +5181,8 @@ "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", "requires": { - "coinstring": "2.3.0", - "secp256k1": "3.5.0" + "coinstring": "^2.0.0", + "secp256k1": "^3.0.1" } }, "he": { @@ -5233,9 +5196,9 @@ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { - "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, "hoek": { @@ -5248,8 +5211,8 @@ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "hosted-git-info": { @@ -5265,7 +5228,7 @@ "depd": "1.1.1", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": "1.4.0" + "statuses": ">= 1.3.1 < 2" }, "dependencies": { "depd": { @@ -5285,9 +5248,9 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "https-browserify": { @@ -5301,12 +5264,12 @@ "integrity": "sha1-LYzxwkciYCwgQdAbpq5eqlE4jw4=", "dev": true, "requires": { - "debug": "2.6.9", - "make-plural": "3.0.6", - "math-interval-parser": "1.1.0", - "messageformat": "0.3.1", - "mustache": "2.3.0", - "sprintf-js": "1.0.3" + "debug": "*", + "make-plural": "^3.0.3", + "math-interval-parser": "^1.1.0", + "messageformat": "^0.3.1", + "mustache": "*", + "sprintf-js": ">=1.0.3" } }, "iconv-lite": { @@ -5331,8 +5294,8 @@ "integrity": "sha1-2ln7hYl25KXkNwLM0fKC/byeV1Y=", "dev": true, "requires": { - "editions": "1.3.4", - "ignorepatterns": "1.1.0" + "editions": "^1.3.3", + "ignorepatterns": "^1.1.0" } }, "ignorepatterns": { @@ -5362,8 +5325,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -5381,7 +5344,7 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, "invert-kv": { @@ -5399,7 +5362,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-arrayish": { @@ -5412,7 +5375,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "requires": { - "binary-extensions": "1.11.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -5425,7 +5388,7 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-callable": { @@ -5438,7 +5401,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-date-object": { @@ -5451,9 +5414,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -5475,7 +5438,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -5489,7 +5452,7 @@ "integrity": "sha1-JE4UDfdbscmjEG9BL/GC+1NKbWI=", "dev": true, "requires": { - "extended": "0.0.6" + "extended": "~0.0.3" } }, "is-extglob": { @@ -5503,7 +5466,7 @@ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fn": { @@ -5527,7 +5490,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-hex-prefixed": { @@ -5541,7 +5504,7 @@ "integrity": "sha1-n69ltvttskt/XAYoR16nH5iEAeI=", "dev": true, "requires": { - "define-properties": "1.1.2" + "define-properties": "^1.1.1" } }, "is-natural-number": { @@ -5555,7 +5518,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-obj": { @@ -5574,7 +5537,7 @@ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", "requires": { - "is-number": "4.0.0" + "is-number": "^4.0.0" }, "dependencies": { "is-number": { @@ -5596,7 +5559,7 @@ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { - "is-path-inside": "1.0.1" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { @@ -5605,7 +5568,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-obj": { @@ -5618,7 +5581,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -5651,7 +5614,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "requires": { - "has": "1.0.1" + "has": "^1.0.1" } }, "is-resolvable": { @@ -5715,8 +5678,8 @@ "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "dev": true, "requires": { - "node-fetch": "1.7.3", - "whatwg-fetch": "2.0.3" + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" } }, "isstream": { @@ -5730,20 +5693,20 @@ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, "requires": { - "abbrev": "1.0.9", - "async": "1.5.2", - "escodegen": "1.8.1", - "esprima": "2.7.3", - "glob": "5.0.15", - "handlebars": "4.0.11", - "js-yaml": "3.11.0", - "mkdirp": "0.5.1", - "nopt": "3.0.6", - "once": "1.4.0", - "resolve": "1.1.7", - "supports-color": "3.2.3", - "which": "1.3.0", - "wordwrap": "1.0.0" + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" }, "dependencies": { "esprima": { @@ -5758,11 +5721,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-flag": { @@ -5783,29 +5746,18 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } }, - "istextorbinary": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", - "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", - "dev": true, - "requires": { - "binaryextensions": "2.1.1", - "editions": "1.3.4", - "textextensions": "2.2.0" - } - }, "isurl": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", "requires": { - "has-to-string-tag-x": "1.4.1", - "is-object": "1.0.1" + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" } }, "js-sha3": { @@ -5829,8 +5781,8 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "requires": { - "argparse": "1.0.10", - "esprima": "4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "jsbn": { @@ -5854,11 +5806,11 @@ "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.6.1.tgz", "integrity": "sha512-xYuD9M1pcld5OKPzVAoEG5MKtnR8iKMyNzRpeS3/mCJ7dcAcS67vqfOmYLoaIQfVRU5uClThbjri3VFR0vEwYg==", "requires": { - "async": "2.6.0", - "babel-preset-env": "1.6.1", - "babelify": "7.3.0", - "json-rpc-error": "2.0.0", - "promise-to-callback": "1.0.0" + "async": "^2.0.1", + "babel-preset-env": "^1.3.2", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0" }, "dependencies": { "async": { @@ -5866,7 +5818,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } } } @@ -5876,7 +5828,7 @@ "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", "requires": { - "inherits": "2.0.3" + "inherits": "^2.0.1" } }, "json-rpc-random-id": { @@ -5899,7 +5851,7 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stable-stringify-without-jsonify": { @@ -5933,7 +5885,7 @@ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "jsonify": { @@ -5957,10 +5909,10 @@ "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", "requires": { - "bindings": "1.3.0", - "inherits": "2.0.3", - "nan": "2.9.2", - "safe-buffer": "5.1.1" + "bindings": "^1.2.1", + "inherits": "^2.0.3", + "nan": "^2.2.1", + "safe-buffer": "^5.1.0" } }, "keccakjs": { @@ -5968,8 +5920,8 @@ "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", "requires": { - "browserify-sha3": "0.0.1", - "sha3": "1.2.0" + "browserify-sha3": "^0.0.1", + "sha3": "^1.1.0" } }, "kind-of": { @@ -5977,7 +5929,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "klaw": { @@ -5985,7 +5937,7 @@ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.9" } }, "lazy-cache": { @@ -5998,7 +5950,7 @@ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "lcov-parse": { @@ -6016,7 +5968,7 @@ "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", "requires": { - "errno": "0.1.7" + "errno": "~0.1.1" } }, "level-iterator-stream": { @@ -6024,10 +5976,10 @@ "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", "requires": { - "inherits": "2.0.3", - "level-errors": "1.0.5", - "readable-stream": "1.1.14", - "xtend": "4.0.1" + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" }, "dependencies": { "isarray": { @@ -6040,10 +5992,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -6058,8 +6010,8 @@ "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", "requires": { - "readable-stream": "1.0.34", - "xtend": "2.1.2" + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" }, "dependencies": { "isarray": { @@ -6072,10 +6024,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -6088,7 +6040,7 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", "requires": { - "object-keys": "0.4.0" + "object-keys": "~0.4.0" } } } @@ -6098,13 +6050,13 @@ "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", "requires": { - "deferred-leveldown": "1.2.2", - "level-codec": "7.0.1", - "level-errors": "1.0.5", - "level-iterator-stream": "1.3.1", - "prr": "1.0.1", - "semver": "5.4.1", - "xtend": "4.0.1" + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" }, "dependencies": { "semver": { @@ -6120,8 +6072,8 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "loader-runner": { @@ -6134,9 +6086,9 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" } }, "locate-path": { @@ -6144,8 +6096,8 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { @@ -6179,7 +6131,7 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "requires": { - "js-tokens": "3.0.2" + "js-tokens": "^3.0.0" } }, "lowercase-keys": { @@ -6192,8 +6144,8 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "lru-queue": { @@ -6202,7 +6154,7 @@ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", "dev": true, "requires": { - "es5-ext": "0.10.39" + "es5-ext": "~0.10.2" } }, "ltgt": { @@ -6215,7 +6167,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "make-plural": { @@ -6224,7 +6176,7 @@ "integrity": "sha1-IDOgO6wpC487uRJY9lud9+iwHKc=", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" }, "dependencies": { "minimist": { @@ -6246,7 +6198,7 @@ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "math-interval-parser": { @@ -6255,7 +6207,7 @@ "integrity": "sha1-2+2lsGsySZc8bfYXD94jhvCv2JM=", "dev": true, "requires": { - "xregexp": "2.0.0" + "xregexp": "^2.0.0" } }, "md5.js": { @@ -6263,8 +6215,8 @@ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" }, "dependencies": { "hash-base": { @@ -6272,8 +6224,8 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } } } @@ -6288,7 +6240,7 @@ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "memdown": { @@ -6296,12 +6248,12 @@ "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", "requires": { - "abstract-leveldown": "2.7.2", - "functional-red-black-tree": "1.0.1", - "immediate": "3.2.3", - "inherits": "2.0.3", - "ltgt": "2.2.0", - "safe-buffer": "5.1.1" + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" }, "dependencies": { "abstract-leveldown": { @@ -6309,7 +6261,7 @@ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", "requires": { - "xtend": "4.0.1" + "xtend": "~4.0.0" } } } @@ -6320,14 +6272,14 @@ "integrity": "sha512-sprBu6nwxBWBvBOh5v2jcsGqiGLlL2xr2dLub3vR8dnE8YB17omwtm/0NSHl8jjNbcsJd5GMWJAnTSVe/O0Wfg==", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-weak-map": "2.0.2", - "event-emitter": "0.3.5", - "is-promise": "2.1.0", - "lru-queue": "0.1.0", - "next-tick": "1.0.0", - "timers-ext": "0.1.3" + "d": "1", + "es5-ext": "^0.10.30", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.2" } }, "memory-fs": { @@ -6335,8 +6287,8 @@ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.5" + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } }, "memorystream": { @@ -6354,14 +6306,14 @@ "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", "requires": { - "async": "1.5.2", - "ethereumjs-util": "5.1.5", + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", "level-ws": "0.0.0", - "levelup": "1.3.9", - "memdown": "1.4.1", - "readable-stream": "2.3.5", - "rlp": "2.0.0", - "semaphore": "1.1.0" + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" }, "dependencies": { "ethereumjs-util": { @@ -6369,13 +6321,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -6386,11 +6338,11 @@ "integrity": "sha1-5Y//gkXps5cXmeW0PbWLPpQX9aI=", "dev": true, "requires": { - "async": "1.5.2", - "glob": "6.0.4", - "make-plural": "3.0.6", - "nopt": "3.0.6", - "watchr": "2.4.13" + "async": "~1.5.2", + "glob": "~6.0.4", + "make-plural": "~3.0.3", + "nopt": "~3.0.6", + "watchr": "~2.4.13" }, "dependencies": { "glob": { @@ -6399,11 +6351,11 @@ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } } } @@ -6419,19 +6371,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, "miller-rabin": { @@ -6439,8 +6391,8 @@ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "requires": { - "bn.js": "4.11.6", - "brorand": "1.1.0" + "bn.js": "^4.0.0", + "brorand": "^1.0.1" } }, "mime": { @@ -6458,7 +6410,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "requires": { - "mime-db": "1.33.0" + "mime-db": "~1.33.0" } }, "mimic-fn": { @@ -6476,7 +6428,7 @@ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", "requires": { - "dom-walk": "0.1.1" + "dom-walk": "^0.1.0" } }, "minimalistic-assert": { @@ -6494,7 +6446,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -6507,8 +6459,8 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -6516,7 +6468,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -6534,7 +6486,7 @@ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", "requires": { - "mkdirp": "0.5.1" + "mkdirp": "*" } }, "mocha": { @@ -6594,7 +6546,7 @@ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } } } @@ -6616,7 +6568,7 @@ "integrity": "sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A==", "dev": true, "requires": { - "moment": "2.22.2" + "moment": ">= 2.9.0" } }, "mout": { @@ -6635,8 +6587,8 @@ "integrity": "sha512-HwJGEKPCpLlNlgGQA56CYh/Wsqa+c4JAq8+mheIgw7OK5T4QvNJqgp6TH8gZ4q4l1aiWeNat/H/MrFXmTuoFfQ==", "dev": true, "requires": { - "bs58": "4.0.1", - "varint": "5.0.0" + "bs58": "^4.0.1", + "varint": "^5.0.0" }, "dependencies": { "base-x": { @@ -6645,7 +6597,7 @@ "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "bs58": { @@ -6654,7 +6606,7 @@ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dev": true, "requires": { - "base-x": "3.0.4" + "base-x": "^3.0.2" } } } @@ -6676,9 +6628,9 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "requires": { - "any-promise": "1.3.0", - "object-assign": "4.1.1", - "thenify-all": "1.6.0" + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" } }, "nan": { @@ -6696,18 +6648,18 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-odd": "2.0.0", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-odd": "^2.0.0", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "arr-diff": { @@ -6761,8 +6713,8 @@ "integrity": "sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw==", "dev": true, "requires": { - "clone": "2.1.1", - "lodash": "4.17.5" + "clone": "2.x", + "lodash": "4.x" }, "dependencies": { "clone": { @@ -6778,8 +6730,8 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" + "encoding": "^0.1.11", + "is-stream": "^1.0.1" } }, "node-libs-browser": { @@ -6787,28 +6739,28 @@ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "requires": { - "assert": "1.4.1", - "browserify-zlib": "0.2.0", - "buffer": "4.9.1", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "domain-browser": "1.2.0", - "events": "1.1.1", - "https-browserify": "1.0.0", - "os-browserify": "0.3.0", + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "readable-stream": "2.3.5", - "stream-browserify": "2.0.1", - "stream-http": "2.8.2", - "string_decoder": "1.0.3", - "timers-browserify": "2.0.10", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", + "url": "^0.11.0", + "util": "^0.10.3", "vm-browserify": "0.0.4" }, "dependencies": { @@ -6817,9 +6769,9 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.10", - "isarray": "1.0.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "process": { @@ -6835,9 +6787,9 @@ "integrity": "sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A==", "dev": true, "requires": { - "cron-parser": "2.5.0", + "cron-parser": "^2.4.0", "long-timeout": "0.1.1", - "sorted-array-functions": "1.2.0" + "sorted-array-functions": "^1.0.0" } }, "nopt": { @@ -6846,7 +6798,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1.0.9" + "abbrev": "1" } }, "normalize-package-data": { @@ -6854,10 +6806,10 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "requires": { - "hosted-git-info": "2.6.0", - "is-builtin-module": "1.0.0", - "semver": "5.5.0", - "validate-npm-package-license": "3.0.3" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { @@ -6865,7 +6817,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } }, "npm-run-path": { @@ -6873,7 +6825,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "number-is-nan": { @@ -6905,9 +6857,9 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -6915,7 +6867,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -6926,9 +6878,9 @@ "integrity": "sha1-hP0j9WsVWCrrPoiwXLVdJDLWijM=", "dev": true, "requires": { - "array-extended": "0.0.11", - "extended": "0.0.6", - "is-extended": "0.0.10" + "array-extended": "~0.0.4", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "object-inspect": { @@ -6946,7 +6898,7 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -6962,8 +6914,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "object.pick": { @@ -6971,7 +6923,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -6986,7 +6938,7 @@ "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", "requires": { - "http-https": "1.0.0" + "http-https": "^1.0.0" } }, "on-finished": { @@ -7002,7 +6954,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -7011,7 +6963,7 @@ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "openzeppelin-solidity": { @@ -7025,8 +6977,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" }, "dependencies": { "wordwrap": { @@ -7043,12 +6995,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "original-require": { @@ -7072,9 +7024,9 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" } }, "os-tmpdir": { @@ -7092,7 +7044,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "requires": { - "p-try": "1.0.0" + "p-try": "^1.0.0" } }, "p-locate": { @@ -7100,7 +7052,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "1.2.0" + "p-limit": "^1.1.0" } }, "p-try": { @@ -7118,11 +7070,11 @@ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "requires": { - "asn1.js": "4.10.1", - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.14" + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" } }, "parse-glob": { @@ -7131,10 +7083,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-headers": { @@ -7142,7 +7094,7 @@ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", "requires": { - "for-each": "0.3.2", + "for-each": "^0.3.2", "trim": "0.0.1" } }, @@ -7202,11 +7154,11 @@ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "pegjs": { @@ -7240,7 +7192,7 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pkg-dir": { @@ -7249,7 +7201,7 @@ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { - "find-up": "1.1.2" + "find-up": "^1.0.0" }, "dependencies": { "find-up": { @@ -7258,8 +7210,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "path-exists": { @@ -7268,7 +7220,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } } } @@ -7329,7 +7281,7 @@ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, "requires": { - "asap": "2.0.6" + "asap": "~2.0.3" } }, "promise-to-callback": { @@ -7337,8 +7289,8 @@ "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", "requires": { - "is-fn": "1.0.0", - "set-immediate-shim": "1.0.1" + "is-fn": "^1.0.0", + "set-immediate-shim": "^1.0.1" } }, "prop-types": { @@ -7347,8 +7299,8 @@ "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "dev": true, "requires": { - "loose-envify": "1.3.1", - "object-assign": "4.1.1" + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, "proxy-addr": { @@ -7356,7 +7308,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.6.0" } }, @@ -7375,11 +7327,11 @@ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", "requires": { - "bn.js": "4.11.6", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" } }, "punycode": { @@ -7397,9 +7349,9 @@ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.0.tgz", "integrity": "sha512-F3DkxxlY0AqD/rwe4YAwjRE2HjOkKW7TxsuteyrS/Jbwrxw887PqYBL4sWUJ9D/V1hmFns0SCD6FDyvlwo9RCQ==", "requires": { - "decode-uri-component": "0.2.0", - "object-assign": "4.1.1", - "strict-uri-encode": "1.1.0" + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" } }, "querystring": { @@ -7418,8 +7370,8 @@ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "is-number": { @@ -7428,7 +7380,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -7437,7 +7389,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -7448,7 +7400,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -7458,7 +7410,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.1.0" } }, "randomfill": { @@ -7466,8 +7418,8 @@ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "requires": { - "randombytes": "2.0.6", - "safe-buffer": "5.1.1" + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" } }, "randomhex": { @@ -7497,10 +7449,10 @@ "integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==", "dev": true, "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" } }, "react-dom": { @@ -7509,10 +7461,10 @@ "integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==", "dev": true, "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" } }, "readable-stream": { @@ -7520,13 +7472,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -7534,10 +7486,10 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.5", - "set-immediate-shim": "1.0.1" + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" } }, "readline-sync": { @@ -7550,7 +7502,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "requires": { - "resolve": "1.5.0" + "resolve": "^1.1.6" } }, "regenerate": { @@ -7568,9 +7520,9 @@ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "private": "0.1.8" + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" } }, "regex-cache": { @@ -7579,7 +7531,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "0.1.3" + "is-equal-shallow": "^0.1.3" } }, "regex-not": { @@ -7587,8 +7539,8 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "regexpp": { @@ -7602,9 +7554,9 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "requires": { - "regenerate": "1.3.3", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "regjsgen": { @@ -7617,7 +7569,7 @@ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } }, "remove-trailing-separator": { @@ -7640,7 +7592,25 @@ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" + } + }, + "req-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-1.0.1.tgz", + "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", + "dev": true, + "requires": { + "req-from": "^1.0.1" + } + }, + "req-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-1.0.1.tgz", + "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", + "dev": true, + "requires": { + "resolve-from": "^2.0.0" } }, "request": { @@ -7648,28 +7618,28 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" } }, "require-directory": { @@ -7693,8 +7663,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" }, "dependencies": { "resolve-from": { @@ -7710,9 +7680,15 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -7724,8 +7700,8 @@ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, "resumer": { @@ -7733,7 +7709,7 @@ "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", "requires": { - "through": "2.3.8" + "through": "~2.3.4" } }, "ret": { @@ -7746,7 +7722,7 @@ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "requires": { - "align-text": "0.1.4" + "align-text": "^0.1.1" } }, "rimraf": { @@ -7759,8 +7735,8 @@ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", "requires": { - "hash-base": "2.0.2", - "inherits": "2.0.3" + "hash-base": "^2.0.0", + "inherits": "^2.0.1" } }, "rlp": { @@ -7774,7 +7750,7 @@ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { - "is-promise": "2.1.0" + "is-promise": "^2.1.0" } }, "rustbn.js": { @@ -7794,7 +7770,7 @@ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "dev": true, "requires": { - "rx-lite": "4.0.8" + "rx-lite": "*" } }, "safe": { @@ -7813,7 +7789,7 @@ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safefs": { @@ -7822,7 +7798,7 @@ "integrity": "sha1-gXDBRE1wOOCMrqBaN0+uL6NJ4Vw=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "*" } }, "scandirectory": { @@ -7831,9 +7807,9 @@ "integrity": "sha1-bOA/VKCQtmjjy+2/IO354xBZPnI=", "dev": true, "requires": { - "ignorefs": "1.2.0", - "safefs": "3.2.2", - "taskgroup": "4.3.1" + "ignorefs": "^1.0.0", + "safefs": "^3.1.2", + "taskgroup": "^4.0.5" } }, "scrypt": { @@ -7841,7 +7817,7 @@ "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", "requires": { - "nan": "2.9.2" + "nan": "^2.0.8" } }, "scrypt-async": { @@ -7860,8 +7836,8 @@ "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", "requires": { - "scrypt": "6.0.3", - "scryptsy": "1.2.1" + "scrypt": "^6.0.2", + "scryptsy": "^1.2.1" } }, "scryptsy": { @@ -7869,7 +7845,7 @@ "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", "requires": { - "pbkdf2": "3.0.14" + "pbkdf2": "^3.0.3" } }, "secp256k1": { @@ -7877,14 +7853,14 @@ "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", "requires": { - "bindings": "1.3.0", - "bip66": "1.1.5", - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "drbg.js": "1.0.1", - "elliptic": "6.4.0", - "nan": "2.9.2", - "safe-buffer": "5.1.1" + "bindings": "^1.2.1", + "bip66": "^1.1.3", + "bn.js": "^4.11.3", + "create-hash": "^1.1.2", + "drbg.js": "^1.0.1", + "elliptic": "^6.2.3", + "nan": "^2.2.1", + "safe-buffer": "^5.1.0" } }, "seek-bzip": { @@ -7892,7 +7868,7 @@ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", "requires": { - "commander": "2.8.1" + "commander": "~2.8.1" }, "dependencies": { "commander": { @@ -7900,7 +7876,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "requires": { - "graceful-readlink": "1.0.1" + "graceful-readlink": ">= 1.0.0" } } } @@ -7921,18 +7897,18 @@ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.2", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" } }, "serve-static": { @@ -7940,9 +7916,9 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, @@ -7951,11 +7927,11 @@ "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", "requires": { - "body-parser": "1.18.2", - "cors": "2.8.4", - "express": "4.16.3", - "request": "2.85.0", - "xhr": "2.4.1" + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" } }, "set-blocking": { @@ -7973,10 +7949,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -7984,7 +7960,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -8004,8 +7980,8 @@ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "sha3": { @@ -8013,7 +7989,7 @@ "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.0.tgz", "integrity": "sha1-aYnxtwpJhwWHajc+LGKs6WqpOZo=", "requires": { - "nan": "2.9.2" + "nan": "^2.0.5" } }, "shebang-command": { @@ -8021,7 +7997,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -8034,9 +8010,9 @@ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", "requires": { - "glob": "7.1.2", - "interpret": "1.1.0", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "signal-exit": { @@ -8054,9 +8030,9 @@ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz", "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==", "requires": { - "decompress-response": "3.3.0", - "once": "1.4.0", - "simple-concat": "1.0.0" + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, "slash": { @@ -8069,14 +8045,14 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.0" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -8084,7 +8060,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -8092,7 +8068,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -8102,9 +8078,9 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -8112,7 +8088,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -8120,7 +8096,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -8128,7 +8104,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -8136,9 +8112,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -8158,7 +8134,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" } }, "sntp": { @@ -8166,7 +8142,7 @@ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "sol-digger": { @@ -8187,12 +8163,12 @@ "integrity": "sha512-12Z84jxeb5VFlQOGS38HOiTrHYohU07oQ5wHOcFJmcRRbaL5kWN7IcldMO1QdW8kONyKdj0xhukzLlN5m5ix4w==", "dev": true, "requires": { - "bluebird": "3.5.1", - "cli-color": "1.2.0", - "commander": "2.14.1", - "debug": "3.1.0", - "fs-extra": "4.0.3", - "glob": "7.1.2" + "bluebird": "^3.5.0", + "cli-color": "^1.2.0", + "commander": "^2.11.0", + "debug": "^3.0.1", + "fs-extra": "^4.0.2", + "glob": "^7.1.2" }, "dependencies": { "debug": { @@ -8211,11 +8187,11 @@ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", "requires": { - "fs-extra": "0.30.0", - "memorystream": "0.3.1", - "require-from-string": "1.2.1", - "semver": "5.5.0", - "yargs": "4.8.1" + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" }, "dependencies": { "camelcase": { @@ -8228,9 +8204,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, "find-up": { @@ -8238,8 +8214,8 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "fs-extra": { @@ -8247,11 +8223,11 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.2.8" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } }, "is-fullwidth-code-point": { @@ -8259,7 +8235,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "jsonfile": { @@ -8267,7 +8243,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "load-json-file": { @@ -8275,11 +8251,11 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "os-locale": { @@ -8287,7 +8263,7 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { - "lcid": "1.0.0" + "lcid": "^1.0.0" } }, "parse-json": { @@ -8295,7 +8271,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-exists": { @@ -8303,7 +8279,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-type": { @@ -8311,9 +8287,9 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -8326,9 +8302,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -8336,8 +8312,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "string-width": { @@ -8345,9 +8321,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "which-module": { @@ -8360,20 +8336,20 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "requires": { - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "lodash.assign": "4.2.0", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", - "window-size": "0.2.0", - "y18n": "3.2.1", - "yargs-parser": "2.4.1" + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" } }, "yargs-parser": { @@ -8381,8 +8357,8 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "requires": { - "camelcase": "3.0.0", - "lodash.assign": "4.2.0" + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" } } } @@ -8393,20 +8369,21 @@ "integrity": "sha512-qikdsSi6+9XbfvwA0aI7HUVpF9fIFNqRWTw23M89GMDY+b6Gj0wWU9IngJS0fimoZIAdEp3bfChxvpfVcrUesg==", "dev": true, "requires": { - "death": "1.1.0", + "death": "^1.1.0", "ethereumjs-testrpc-sc": "6.1.6", - "istanbul": "0.4.5", - "keccakjs": "0.2.1", - "req-cwd": "1.0.1", - "shelljs": "0.7.8", - "sol-explore": "1.6.2", + "istanbul": "^0.4.5", + "keccakjs": "^0.2.1", + "req-cwd": "^1.0.1", + "shelljs": "^0.7.4", + "sol-explore": "^1.6.2", "solidity-parser-sc": "0.4.11", - "tree-kill": "1.2.0", - "web3": "0.18.4" + "tree-kill": "^1.2.0", + "web3": "^0.18.4" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "dev": true }, "shelljs": { @@ -8415,9 +8392,9 @@ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true, "requires": { - "glob": "7.1.2", - "interpret": "1.1.0", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "sol-explore": { @@ -8433,10 +8410,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -8447,13 +8424,13 @@ "integrity": "sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g==", "dev": true, "requires": { - "commander": "2.14.1", - "lodash": "4.17.5", - "mocha": "5.2.0", - "mustache": "2.3.0", - "react": "16.4.2", - "react-dom": "16.4.2", - "shelljs": "0.8.2" + "commander": "^2.14.1", + "lodash": "^4.17.5", + "mocha": "^5.0.1", + "mustache": "^2.3.0", + "react": "^16.2.0", + "react-dom": "^16.2.0", + "shelljs": "^0.8.1" }, "dependencies": { "browser-stdout": { @@ -8512,9 +8489,9 @@ "integrity": "sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw==", "dev": true, "requires": { - "mocha": "4.1.0", - "pegjs": "0.10.0", - "yargs": "4.8.1" + "mocha": "^4.1.0", + "pegjs": "^0.10.0", + "yargs": "^4.6.0" }, "dependencies": { "camelcase": { @@ -8529,9 +8506,9 @@ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, "find-up": { @@ -8540,8 +8517,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "is-fullwidth-code-point": { @@ -8550,7 +8527,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "load-json-file": { @@ -8559,11 +8536,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "os-locale": { @@ -8572,7 +8549,7 @@ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { - "lcid": "1.0.0" + "lcid": "^1.0.0" } }, "parse-json": { @@ -8581,7 +8558,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-exists": { @@ -8590,7 +8567,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-type": { @@ -8599,9 +8576,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -8616,9 +8593,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -8627,8 +8604,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "string-width": { @@ -8637,9 +8614,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "which-module": { @@ -8654,20 +8631,20 @@ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "dev": true, "requires": { - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "lodash.assign": "4.2.0", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", - "window-size": "0.2.0", - "y18n": "3.2.1", - "yargs-parser": "2.4.1" + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" } }, "yargs-parser": { @@ -8676,8 +8653,8 @@ "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "dev": true, "requires": { - "camelcase": "3.0.0", - "lodash.assign": "4.2.0" + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" } } } @@ -8688,17 +8665,17 @@ "integrity": "sha512-hCZr5cEK2H6LVC1Lr7IGPGJ8Bs4Ktif9cmwnk3BHpoZLIwTtrNE0LUtTRBxkO3/G0GGB4OdxnnJT1pbgsJ/2Uw==", "dev": true, "requires": { - "ajv": "5.5.2", - "chokidar": "1.7.0", - "colors": "1.2.1", - "commander": "2.14.1", - "js-string-escape": "1.0.1", - "lodash": "4.17.5", + "ajv": "^5.2.2", + "chokidar": "^1.6.0", + "colors": "^1.1.2", + "commander": "^2.9.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.14.2", "sol-digger": "0.0.2", "sol-explore": "1.6.1", "solium-plugin-security": "0.1.1", "solparse": "2.2.4", - "text-table": "0.2.0" + "text-table": "^0.2.0" } }, "solium-plugin-security": { @@ -8713,9 +8690,9 @@ "integrity": "sha512-Sdyk983juUaOITdTD9U5Yc+MaX8kz4pN3wFyCRILWXW3+Ff96PxY9RLBuZINYbBgCAXN1a+kThJfFMlaXG9R6A==", "dev": true, "requires": { - "mocha": "4.1.0", - "pegjs": "0.10.0", - "yargs": "10.1.2" + "mocha": "^4.0.1", + "pegjs": "^0.10.0", + "yargs": "^10.0.3" }, "dependencies": { "commander": { @@ -8775,7 +8752,7 @@ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } }, "yargs": { @@ -8784,18 +8761,18 @@ "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", "dev": true, "requires": { - "cliui": "4.0.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "8.1.0" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^8.1.0" } }, "yargs-parser": { @@ -8804,7 +8781,7 @@ "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } } } @@ -8830,11 +8807,11 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "requires": { - "atob": "2.1.1", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-support": { @@ -8842,7 +8819,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "requires": { - "source-map": "0.5.7" + "source-map": "^0.5.6" } }, "source-map-url": { @@ -8855,8 +8832,8 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.0" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { @@ -8869,8 +8846,8 @@ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "requires": { - "spdx-exceptions": "2.1.0", - "spdx-license-ids": "3.0.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { @@ -8883,7 +8860,7 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "sprintf-js": { @@ -8896,14 +8873,14 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" } }, "stack-trace": { @@ -8917,8 +8894,8 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -8926,7 +8903,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -8947,8 +8924,8 @@ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.5" + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" } }, "stream-http": { @@ -8956,11 +8933,11 @@ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" }, "dependencies": { "readable-stream": { @@ -8968,13 +8945,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "string_decoder": { @@ -8982,7 +8959,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } } } @@ -8998,10 +8975,10 @@ "integrity": "sha1-dBlX3/SHsCcqee7FpE8jnubxfM0=", "dev": true, "requires": { - "array-extended": "0.0.11", - "date-extended": "0.0.6", - "extended": "0.0.6", - "is-extended": "0.0.10" + "array-extended": "~0.0.5", + "date-extended": "~0.0.3", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "string-width": { @@ -9009,8 +8986,8 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "dependencies": { "ansi-regex": { @@ -9023,7 +9000,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -9033,9 +9010,9 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.10.0", - "function-bind": "1.1.1" + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" } }, "string_decoder": { @@ -9043,7 +9020,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "stringstream": { @@ -9056,7 +9033,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -9064,7 +9041,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "strip-dirs": { @@ -9072,7 +9049,7 @@ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", "requires": { - "is-natural-number": "4.0.1" + "is-natural-number": "^4.0.1" } }, "strip-eof": { @@ -9099,7 +9076,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "swarm-js": { @@ -9107,19 +9084,19 @@ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", "requires": { - "bluebird": "3.5.1", - "buffer": "5.1.0", - "decompress": "4.2.0", - "eth-lib": "0.1.27", - "fs-extra": "2.1.2", - "fs-promise": "2.0.3", - "got": "7.1.0", - "mime-types": "2.1.18", - "mkdirp-promise": "5.0.1", - "mock-fs": "4.4.2", - "setimmediate": "1.0.5", - "tar.gz": "1.0.7", - "xhr-request-promise": "0.1.2" + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "decompress": "^4.0.0", + "eth-lib": "^0.1.26", + "fs-extra": "^2.1.2", + "fs-promise": "^2.0.0", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar.gz": "^1.0.5", + "xhr-request-promise": "^0.1.2" }, "dependencies": { "fs-extra": { @@ -9127,8 +9104,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" } }, "got": { @@ -9136,20 +9113,20 @@ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", "requires": { - "decompress-response": "3.3.0", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-plain-obj": "1.1.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "isurl": "1.0.0", - "lowercase-keys": "1.0.0", - "p-cancelable": "0.3.0", - "p-timeout": "1.2.1", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "url-parse-lax": "1.0.0", - "url-to-options": "1.0.1" + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" } }, "jsonfile": { @@ -9157,7 +9134,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "p-cancelable": { @@ -9170,7 +9147,7 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", "requires": { - "p-finally": "1.0.0" + "p-finally": "^1.0.0" } }, "prepend-http": { @@ -9183,7 +9160,7 @@ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } } } @@ -9194,12 +9171,12 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "chalk": "2.3.2", - "lodash": "4.17.5", + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", "slice-ansi": "1.0.0", - "string-width": "2.1.1" + "string-width": "^2.1.1" }, "dependencies": { "ansi-styles": { @@ -9208,7 +9185,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -9217,9 +9194,9 @@ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "slice-ansi": { @@ -9228,7 +9205,7 @@ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0" + "is-fullwidth-code-point": "^2.0.0" } }, "supports-color": { @@ -9237,7 +9214,7 @@ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -9247,19 +9224,19 @@ "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.0.tgz", "integrity": "sha512-j0jO9BiScfqtPBb9QmPLL0qvxXMz98xjkMb7x8lKipFlJZwNJkqkWPou+NU4V6T9RnVh1kuSthLE8gLrN8bBfw==", "requires": { - "deep-equal": "1.0.1", - "defined": "1.0.0", - "for-each": "0.3.2", - "function-bind": "1.1.1", - "glob": "7.1.2", - "has": "1.0.1", - "inherits": "2.0.3", - "minimist": "1.2.0", - "object-inspect": "1.5.0", - "resolve": "1.5.0", - "resumer": "0.0.0", - "string.prototype.trim": "1.1.2", - "through": "2.3.8" + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.2", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.1", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.5.0", + "resolve": "~1.5.0", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" }, "dependencies": { "minimist": { @@ -9274,9 +9251,9 @@ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-stream": { @@ -9284,10 +9261,10 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", "requires": { - "bl": "1.2.2", - "end-of-stream": "1.4.1", - "readable-stream": "2.3.5", - "xtend": "4.0.1" + "bl": "^1.0.0", + "end-of-stream": "^1.0.0", + "readable-stream": "^2.0.0", + "xtend": "^4.0.0" } }, "tar.gz": { @@ -9295,11 +9272,11 @@ "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", "requires": { - "bluebird": "2.11.0", - "commander": "2.14.1", - "fstream": "1.0.11", - "mout": "0.11.1", - "tar": "2.2.1" + "bluebird": "^2.9.34", + "commander": "^2.8.1", + "fstream": "^1.0.8", + "mout": "^0.11.0", + "tar": "^2.1.1" }, "dependencies": { "bluebird": { @@ -9315,8 +9292,8 @@ "integrity": "sha1-feGT/r12gnPEV3MElwJNUSwnkVo=", "dev": true, "requires": { - "ambi": "2.5.0", - "csextends": "1.2.0" + "ambi": "^2.2.0", + "csextends": "^1.0.3" } }, "text-table": { @@ -9330,7 +9307,7 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", "requires": { - "any-promise": "1.3.0" + "any-promise": "^1.0.0" } }, "thenify-all": { @@ -9338,7 +9315,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", "requires": { - "thenify": "3.3.0" + "thenify": ">= 3.1.0 < 4" } }, "through": { @@ -9356,7 +9333,7 @@ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "requires": { - "setimmediate": "1.0.5" + "setimmediate": "^1.0.4" } }, "timers-ext": { @@ -9365,8 +9342,8 @@ "integrity": "sha512-2iKErlS+NnEr0aQVQS91/mjsqCDO4OFl+5c5RDNtP+acQJTySvNSdbiSbmBD0t2RbErirF2Vq7x5YPQOSva77Q==", "dev": true, "requires": { - "es5-ext": "0.10.39", - "next-tick": "1.0.0" + "es5-ext": "~0.10.14", + "next-tick": "1" } }, "tingodb": { @@ -9375,10 +9352,10 @@ "integrity": "sha1-9jM2JZr336bJDf4lVqDfsNTu3lk=", "dev": true, "requires": { - "bson": "1.0.9", - "lodash": "4.17.5", - "safe": "0.4.6", - "safe-buffer": "5.1.1" + "bson": "^1.0.4", + "lodash": "^4.17.5", + "safe": "^0.4.5", + "safe-buffer": "^5.1.1" } }, "tmp": { @@ -9387,7 +9364,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.2" } }, "to-arraybuffer": { @@ -9405,7 +9382,7 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "to-regex": { @@ -9413,10 +9390,10 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -9424,8 +9401,8 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" }, "dependencies": { "is-number": { @@ -9433,7 +9410,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } } } @@ -9443,7 +9420,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tree-kill": { @@ -9468,7 +9445,7 @@ "integrity": "sha1-vydYaYi0/4RWPt+/MrR5QUCKdq0=", "dev": true, "requires": { - "mocha": "4.1.0", + "mocha": "^4.1.0", "original-require": "1.0.1", "solc": "0.4.24" } @@ -9484,14 +9461,15 @@ "integrity": "sha512-/1LCtJFf5Jvm5Rv88T0d/rZSKvaiW/yO1SHXLGJgKzLsiG1F/2spFs4HrI1mRxP00opfrYXloEmLtkVV/kcndQ==", "requires": { "ethjs-abi": "0.1.8", - "truffle-blockchain-utils": "0.0.4", - "truffle-contract-schema": "2.0.0", + "truffle-blockchain-utils": "^0.0.4", + "truffle-contract-schema": "^2.0.0", "truffle-error": "0.0.2", - "web3": "0.20.6" + "web3": "^0.20.1" }, "dependencies": { "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" }, "ethjs-abi": { "version": "0.1.8", @@ -9509,10 +9487,10 @@ "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -9522,9 +9500,9 @@ "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-2.0.0.tgz", "integrity": "sha512-nLlspmu1GKDaluWksBwitHi/7Z3IpRjmBYeO9N+T1nVJD2V4IWJaptCKP1NqnPiJA+FChB7+F7pI6Br51/FtXQ==", "requires": { - "ajv": "5.5.2", - "crypto-js": "3.1.9-1", - "debug": "3.1.0" + "ajv": "^5.1.1", + "crypto-js": "^3.1.9-1", + "debug": "^3.1.0" }, "dependencies": { "crypto-js": { @@ -9552,10 +9530,10 @@ "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.1.0.tgz", "integrity": "sha512-Vj04yr2d9qLRZspoHztbE/YQnVaoFb90JNZHtggRUm+JFm/NOiSJHLVI63+3mtUIuQ04EuKZ7Df8JQw0Ni7IeA==", "requires": { - "ethereumjs-tx": "1.3.4", - "ethereumjs-wallet": "0.6.0", - "web3": "0.20.6", - "web3-provider-engine": "13.6.6" + "ethereumjs-tx": "^1.3.3", + "ethereumjs-wallet": "^0.6.0", + "web3": "^0.20.5", + "web3-provider-engine": "^13.6.4" }, "dependencies": { "async": { @@ -9563,11 +9541,12 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" }, "clone": { "version": "2.1.2", @@ -9579,13 +9558,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "web3": { @@ -9594,10 +9573,10 @@ "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } }, "web3-provider-engine": { @@ -9605,25 +9584,25 @@ "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.6.6.tgz", "integrity": "sha512-M9eztIxwCR2U7+d42RXdu3fBjvG/kcv7Ra8z2PHs912aHhAkMtNfvzhC8dboC7yKmj230eVHwouSXKizmSqC7Q==", "requires": { - "async": "2.6.0", - "clone": "2.1.2", - "eth-block-tracker": "2.3.0", - "eth-sig-util": "1.4.2", - "ethereumjs-block": "1.7.1", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "ethereumjs-vm": "2.3.3", - "fetch-ponyfill": "4.1.0", - "json-rpc-error": "2.0.0", - "json-stable-stringify": "1.0.1", - "promise-to-callback": "1.0.0", - "readable-stream": "2.3.5", - "request": "2.85.0", - "semaphore": "1.1.0", - "solc": "0.4.24", - "tape": "4.9.0", - "xhr": "2.4.1", - "xtend": "4.0.1" + "async": "^2.5.0", + "clone": "^2.0.0", + "eth-block-tracker": "^2.2.2", + "eth-sig-util": "^1.4.2", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.1.1", + "ethereumjs-vm": "^2.0.2", + "fetch-ponyfill": "^4.0.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "readable-stream": "^2.2.9", + "request": "^2.67.0", + "semaphore": "^1.0.3", + "solc": "^0.4.2", + "tape": "^4.4.0", + "xhr": "^2.2.0", + "xtend": "^4.0.1" } } } @@ -9634,13 +9613,14 @@ "integrity": "sha1-21nOb6HFWHZgERN1CalN/KjRQI4=", "dev": true, "requires": { - "ethereumjs-wallet": "0.6.0", - "web3": "0.18.4", - "web3-provider-engine": "8.6.1" + "ethereumjs-wallet": "^0.6.0", + "web3": "^0.18.2", + "web3-provider-engine": "^8.4.0" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "dev": true }, "web3": { @@ -9650,10 +9630,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -9668,7 +9648,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -9683,7 +9663,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "type-is": { @@ -9692,7 +9672,7 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.18" + "mime-types": "~2.1.18" } }, "typechecker": { @@ -9712,7 +9692,7 @@ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "requires": { - "is-typedarray": "1.0.0" + "is-typedarray": "^1.0.0" } }, "ua-parser-js": { @@ -9726,9 +9706,9 @@ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" }, "dependencies": { "camelcase": { @@ -9741,8 +9721,8 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", + "center-align": "^0.1.1", + "right-align": "^0.1.1", "wordwrap": "0.0.2" } }, @@ -9761,9 +9741,9 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", "window-size": "0.1.0" } } @@ -9780,9 +9760,9 @@ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", "requires": { - "source-map": "0.5.7", - "uglify-js": "2.8.29", - "webpack-sources": "1.1.0" + "source-map": "^0.5.6", + "uglify-js": "^2.8.29", + "webpack-sources": "^1.0.1" } }, "ultron": { @@ -9795,8 +9775,8 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", "requires": { - "buffer": "3.6.0", - "through": "2.3.8" + "buffer": "^3.0.1", + "through": "^2.3.6" }, "dependencies": { "base64-js": { @@ -9810,8 +9790,8 @@ "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", "requires": { "base64-js": "0.0.8", - "ieee754": "1.1.10", - "isarray": "1.0.0" + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } } } @@ -9821,10 +9801,10 @@ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { @@ -9832,7 +9812,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "set-value": { @@ -9840,10 +9820,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" } } } @@ -9870,8 +9850,8 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -9879,9 +9859,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -9916,7 +9896,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", "requires": { - "punycode": "2.1.0" + "punycode": "^2.1.0" }, "dependencies": { "punycode": { @@ -9962,7 +9942,7 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.2" }, "dependencies": { "kind-of": { @@ -10018,8 +9998,8 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "requires": { - "spdx-correct": "3.0.0", - "spdx-expression-parse": "3.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "varint": { @@ -10038,9 +10018,9 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "vm-browserify": { @@ -10056,9 +10036,9 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "requires": { - "chokidar": "2.0.3", - "graceful-fs": "4.1.11", - "neo-async": "2.5.0" + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" }, "dependencies": { "anymatch": { @@ -10066,8 +10046,8 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "arr-diff": { @@ -10085,16 +10065,16 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.2", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -10102,7 +10082,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -10112,18 +10092,18 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.1.3", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0", - "upath": "1.0.5" + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.1.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.0" } }, "expand-brackets": { @@ -10131,13 +10111,13 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -10145,7 +10125,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -10153,7 +10133,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -10161,7 +10141,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -10169,7 +10149,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -10179,7 +10159,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -10187,7 +10167,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -10197,9 +10177,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } }, "kind-of": { @@ -10214,14 +10194,14 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -10229,7 +10209,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -10237,7 +10217,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -10247,10 +10227,10 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -10258,7 +10238,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -10268,8 +10248,8 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -10277,7 +10257,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -10287,7 +10267,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -10295,7 +10275,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -10303,9 +10283,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-extglob": { @@ -10318,7 +10298,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-number": { @@ -10326,7 +10306,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -10334,7 +10314,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -10354,19 +10334,19 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.9", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } @@ -10377,14 +10357,14 @@ "integrity": "sha1-10hHu01vkPYf4sdPn2hmKqDgdgE=", "dev": true, "requires": { - "eachr": "2.0.4", - "extendr": "2.1.0", - "extract-opts": "2.2.0", - "ignorefs": "1.2.0", - "safefs": "3.2.2", - "scandirectory": "2.5.0", - "taskgroup": "4.3.1", - "typechecker": "2.1.0" + "eachr": "^2.0.2", + "extendr": "^2.1.0", + "extract-opts": "^2.2.0", + "ignorefs": "^1.0.0", + "safefs": "^3.1.2", + "scandirectory": "^2.5.0", + "taskgroup": "^4.2.0", + "typechecker": "^2.0.8" } }, "web3": { @@ -10416,20 +10396,20 @@ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", "requires": { - "decompress-response": "3.3.0", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-plain-obj": "1.1.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "isurl": "1.0.0", - "lowercase-keys": "1.0.0", - "p-cancelable": "0.3.0", - "p-timeout": "1.2.1", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "url-parse-lax": "1.0.0", - "url-to-options": "1.0.1" + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" } }, "p-cancelable": { @@ -10442,7 +10422,7 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", "requires": { - "p-finally": "1.0.0" + "p-finally": "^1.0.0" } }, "prepend-http": { @@ -10460,7 +10440,7 @@ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } } } @@ -10623,9 +10603,9 @@ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", "requires": { - "bn.js": "4.11.6", - "elliptic": "6.4.0", - "xhr-request-promise": "0.1.2" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" } }, "underscore": { @@ -10699,20 +10679,20 @@ "integrity": "sha1-TYbhnjDKr5ffNRUR7A9gE25bMOs=", "dev": true, "requires": { - "async": "2.6.0", - "clone": "2.1.1", - "ethereumjs-block": "1.7.1", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "ethereumjs-vm": "2.3.3", - "isomorphic-fetch": "2.2.1", - "request": "2.85.0", - "semaphore": "1.1.0", - "solc": "0.4.24", - "tape": "4.9.0", - "web3": "0.16.0", - "xhr": "2.4.1", - "xtend": "4.0.1" + "async": "^2.1.2", + "clone": "^2.0.0", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.0.2", + "isomorphic-fetch": "^2.2.0", + "request": "^2.67.0", + "semaphore": "^1.0.3", + "solc": "^0.4.2", + "tape": "^4.4.0", + "web3": "^0.16.0", + "xhr": "^2.2.0", + "xtend": "^4.0.1" }, "dependencies": { "async": { @@ -10721,11 +10701,12 @@ "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", + "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", "dev": true }, "clone": { @@ -10740,13 +10721,13 @@ "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "dev": true, "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "web3": { @@ -10756,9 +10737,9 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xmlhttprequest": "*" } } } @@ -10843,28 +10824,28 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz", "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", "requires": { - "acorn": "5.5.3", - "acorn-dynamic-import": "2.0.2", - "ajv": "6.5.0", - "ajv-keywords": "3.2.0", - "async": "2.6.0", - "enhanced-resolve": "3.4.1", - "escope": "3.6.0", - "interpret": "1.1.0", - "json-loader": "0.5.7", - "json5": "0.5.1", - "loader-runner": "2.3.0", - "loader-utils": "1.1.0", - "memory-fs": "0.4.1", - "mkdirp": "0.5.1", - "node-libs-browser": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.5.0", - "tapable": "0.2.8", - "uglifyjs-webpack-plugin": "0.4.6", - "watchpack": "1.6.0", - "webpack-sources": "1.1.0", - "yargs": "8.0.2" + "acorn": "^5.0.0", + "acorn-dynamic-import": "^2.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "async": "^2.1.2", + "enhanced-resolve": "^3.4.0", + "escope": "^3.6.0", + "interpret": "^1.0.0", + "json-loader": "^0.5.4", + "json5": "^0.5.1", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "mkdirp": "~0.5.0", + "node-libs-browser": "^2.0.0", + "source-map": "^0.5.3", + "supports-color": "^4.2.1", + "tapable": "^0.2.7", + "uglifyjs-webpack-plugin": "^0.4.6", + "watchpack": "^1.4.0", + "webpack-sources": "^1.0.1", + "yargs": "^8.0.2" }, "dependencies": { "ajv": { @@ -10872,10 +10853,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1", - "uri-js": "4.2.1" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0", + "uri-js": "^4.2.1" } }, "ajv-keywords": { @@ -10888,7 +10869,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "cliui": { @@ -10896,9 +10877,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" }, "dependencies": { "string-width": { @@ -10906,9 +10887,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -10918,10 +10899,10 @@ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", "requires": { - "graceful-fs": "4.1.11", - "memory-fs": "0.4.1", - "object-assign": "4.1.1", - "tapable": "0.2.8" + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "object-assign": "^4.0.1", + "tapable": "^0.2.7" } }, "fast-deep-equal": { @@ -10939,7 +10920,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "load-json-file": { @@ -10947,10 +10928,10 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, "parse-json": { @@ -10958,7 +10939,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-type": { @@ -10966,7 +10947,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "requires": { - "pify": "2.3.0" + "pify": "^2.0.0" } }, "pify": { @@ -10979,9 +10960,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "read-pkg-up": { @@ -10989,8 +10970,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "strip-bom": { @@ -11003,7 +10984,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } }, "tapable": { @@ -11016,19 +10997,19 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", "requires": { - "camelcase": "4.1.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "read-pkg-up": "2.0.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "7.0.0" + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" } }, "yargs-parser": { @@ -11036,7 +11017,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } } } @@ -11046,8 +11027,8 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", "requires": { - "source-list-map": "2.0.0", - "source-map": "0.6.1" + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" }, "dependencies": { "source-map": { @@ -11059,11 +11040,12 @@ }, "websocket": { "version": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", + "from": "websocket@git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", "requires": { - "debug": "2.6.9", - "nan": "2.9.2", - "typedarray-to-buffer": "3.1.5", - "yaeti": "0.0.6" + "debug": "^2.2.0", + "nan": "^2.3.3", + "typedarray-to-buffer": "^3.1.2", + "yaeti": "^0.0.6" } }, "whatwg-fetch": { @@ -11077,7 +11059,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "which-module": { @@ -11096,12 +11078,12 @@ "integrity": "sha512-GYKuysPz2pxYAVJD2NPsDLP5Z79SDEzPm9/j4tCjkF/n89iBNGBMJcR+dMUqxgPNgoSs6fVygPi+Vl2oxIpBuw==", "dev": true, "requires": { - "async": "1.0.0", - "colors": "1.0.3", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "stack-trace": "0.0.10" + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" }, "dependencies": { "async": { @@ -11129,8 +11111,8 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" }, "dependencies": { "is-fullwidth-code-point": { @@ -11138,7 +11120,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "string-width": { @@ -11146,9 +11128,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -11164,7 +11146,7 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "ws": { @@ -11172,9 +11154,9 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "requires": { - "async-limiter": "1.0.0", - "safe-buffer": "5.1.1", - "ultron": "1.1.1" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } }, "xhr": { @@ -11182,10 +11164,10 @@ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.1.tgz", "integrity": "sha512-pAIU5vBr9Hiy5cpFIbPnwf0C18ZF86DBsZKrlsf87N5De/JbA6RJ83UP/cv+aljl4S40iRVMqP4pr4sF9Dnj0A==", "requires": { - "global": "4.3.2", - "is-function": "1.0.1", - "parse-headers": "2.0.1", - "xtend": "4.0.1" + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" } }, "xhr-request": { @@ -11193,13 +11175,13 @@ "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", "requires": { - "buffer-to-arraybuffer": "0.0.5", - "object-assign": "4.1.1", - "query-string": "5.1.0", - "simple-get": "2.7.0", - "timed-out": "4.0.1", - "url-set-query": "1.0.0", - "xhr": "2.4.1" + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" } }, "xhr-request-promise": { @@ -11207,7 +11189,7 @@ "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", "requires": { - "xhr-request": "1.1.0" + "xhr-request": "^1.0.1" } }, "xhr2": { @@ -11252,18 +11234,18 @@ "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", "dev": true, "requires": { - "cliui": "4.0.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "9.0.2" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" } }, "yargs-parser": { @@ -11272,7 +11254,7 @@ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } }, "yauzl": { @@ -11280,8 +11262,8 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" } } } diff --git a/test/w_volume_restriction_transfer_manager.js b/test/w_volume_restriction_transfer_manager.js new file mode 100644 index 000000000..868ec0de7 --- /dev/null +++ b/test/w_volume_restriction_transfer_manager.js @@ -0,0 +1,1069 @@ +import latestTime from './helpers/latestTime'; +import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; +import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; +import { encodeProxyCall } from './helpers/encodeCall'; + +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +const SecurityToken = artifacts.require('./SecurityToken.sol'); +const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); +const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); +const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const VolumeRestrictionTransferManagerFactory = artifacts.require('./VolumeRestrictionTransferManagerFactory.sol'); +const VolumeRestrictionTransferManager = artifacts.require('./VolumeRestrictionTransferManager'); +const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); +const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); + +const Web3 = require('web3'); +const BigNumber = require('bignumber.js'); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract('VolumeRestrictionTransferManager', accounts => { + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let P_VolumeRestrictionTransferManagerFactory; + let I_SecurityTokenRegistryProxy; + let P_VolumeRestrictionTransferManager; + let I_GeneralTransferManagerFactory; + let I_VolumeRestrictionTransferManagerFactory; + let I_GeneralPermissionManager; + let I_VolumeRestrictionTransferManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_MRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[7]; + account_investor2 = accounts[8]; + account_investor3 = accounts[9]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4(a): Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 4(b): Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 4(c): Deploy the VolumeRestrictionTransferManager + I_VolumeRestrictionTransferManagerFactory = await VolumeRestrictionTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_VolumeRestrictionTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "VolumeRestrictionTransferManagerFactory contract was not deployed" + ); + + // STEP 4(d): Deploy the VolumeRestrictionTransferManager + P_VolumeRestrictionTransferManagerFactory = await VolumeRestrictionTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); + assert.notEqual( + P_VolumeRestrictionTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "VolumeRestrictionTransferManagerFactory contract was not deployed" + ); + + + // Step 6: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 7: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the VolumeRestrictionTransferManagerFactory + await I_MRProxied.registerModule(I_VolumeRestrictionTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_VolumeRestrictionTransferManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the Paid VolumeRestrictionTransferManagerFactory + await I_MRProxied.registerModule(P_VolumeRestrictionTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_VolumeRestrictionTransferManagerFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + ModuleRegistryProxy: ${ModuleRegistryProxy.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + VolumeRestrictionTransferManagerFactory: ${I_VolumeRestrictionTransferManagerFactory.address} + ----------------------------------------------------------------------------- + `); + }); + + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._types[0].toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + }); + + describe("Buy tokens using on-chain whitelist and test locking them up and attempting to transfer", async() => { + + it("Should Buy the tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('2', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('2', 'ether') + ); + }); + + it("Should Buy some more tokens", async() => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('10', 'ether') + ); + }); + + it("Should unsuccessfully attach the VolumeRestrictionTransferManager factory with the security token", async () => { + let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + try { + const tx = await I_SecurityToken.addModule(P_VolumeRestrictionTransferManagerFactory.address, 0, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because Token is not paid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully attach the VolumeRestrictionTransferManager factory with the security token", async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_VolumeRestrictionTransferManagerFactory.address, 0, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "VolumeRestrictionTransferManagerFactory doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "VolumeRestrictionTransferManager", + "VolumeRestrictionTransferManagerFactory module was not added" + ); + P_VolumeRestrictionTransferManager = VolumeRestrictionTransferManager.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + + it("Should successfully attach the VolumeRestrictionTransferManager with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_VolumeRestrictionTransferManagerFactory.address, 0, 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "VolumeRestrictionTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "VolumeRestrictionTransferManager", + "VolumeRestrictionTransferManager module was not added" + ); + I_VolumeRestrictionTransferManager = VolumeRestrictionTransferManager.at(tx.logs[2].args._module); + }); + + it("Add a new token holder", async() => { + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor3.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('10', 'ether'), { from: token_owner }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor3)).toNumber(), + web3.utils.toWei('10', 'ether') + ); + }); + + it("Should pause the tranfers at transferManager level", async() => { + let tx = await I_VolumeRestrictionTransferManager.pause({from: token_owner}); + }); + + it("Should still be able to transfer between existing token holders up to limit", async() => { + // Add the Investor in to the whitelist + // Mint some tokens + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('3', 'ether') + ); + }); + + it("Should unpause the tranfers at transferManager level", async() => { + await I_VolumeRestrictionTransferManager.unpause({from: token_owner}); + }); + + it("Should prevent the creation of a lockup with bad parameters where the totalAmount is zero", async() => { + let errorThrown = false; + try { + // create a lockup + // this will generate an exception because the totalAmount is zero + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, 0, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> couldn't create lock up because totalAmount is zero`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should prevent the creation of a lockup with bad parameters where the releaseFrequencySeconds is zero", async() => { + let errorThrown = false; + try { + // create a lockup + // this will generate an exception because the releaseFrequencySeconds is zero + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 0, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> couldn't create lock up because releaseFrequencySeconds is zero`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should prevent the creation of a lockup with bad parameters where the lockUpPeriodSeconds is zero", async() => { + let errorThrown = false; + try { + // create a lockup + // this will generate an exception because the lockUpPeriodSeconds is zero + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 0, 4, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> couldn't create lock up because lockUpPeriodSeconds is zero`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + + it("Should prevent the creation of a lockup with bad parameters where the total amount to be released is more granular than allowed by the token", async() => { + let errorThrown = false; + try { + // create a lockup + // this will generate an exception because we're locking up 5e17 tokens but the granularity is 5e18 tokens + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, web3.utils.toWei('0.5', 'ether'), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> couldn't create lock up because the total amount to be released is more granular than allowed by the token`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + + it("Should prevent the creation of a lockup with bad parameters where the lockUpPeriodSeconds is not evenly divisible by releaseFrequencySeconds", async() => { + + // balance should be 9000000000000000000 here (9 eth) + let balance = await I_SecurityToken.balanceOf(account_investor2) + + + let errorThrown = false; + try { + // create a lockup + // over 17 seconds total, with 4 periods. + // this will generate an exception because 17 is not evenly divisble by 4. + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 17, 4, 0, balance, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> couldn't create lock up because lockUpPeriodSeconds must be evenly divisible by releaseFrequencySeconds`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should prevent the creation of a lockup with bad parameters where the total amount being locked up isn't evenly divisible by the number of total periods", async() => { + + let errorThrown = false; + try { + // create a lockup for a balance of 1 eth + // over 16e18 seconds total, with 4e18 periods of 4 seconds each. + // this will generate an exception because 16e18 / 4e18 = 4e18 but the token granularity is 1e18 and 1e18 % 4e18 != 0 + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, web3.utils.toWei('16', 'ether'), 4, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> couldn't create lock up because the total amount being locked up must be evenly divisible by the number of total periods`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should prevent the creation of a lockup with bad parameters where the amount to be released per period is too granular for the token", async() => { + + // balance should be 9000000000000000000 here (9 eth) + let balance = await I_SecurityToken.balanceOf(account_investor2) + + + let errorThrown = false; + try { + // create a lockup for their entire balance + // over 16 seconds total, with 4 periods of 4 seconds each. + // this will generate an exception because 9000000000000000000 / 4 = 2250000000000000000 but the token granularity is 1000000000000000000 + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, balance, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> couldn't create lock up because amount to be released per period is more granular than allowed by the token`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should prevent the transfer of tokens in a lockup", async() => { + + let balance = await I_SecurityToken.balanceOf(account_investor2) + + // create a lockup for their entire balance + // over 12 seconds total, with 3 periods of 4 seconds each. + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 12, 4, 0, balance, { from: token_owner }); + + // read only - check if transfer will pass. it should return INVALID + let result = await I_VolumeRestrictionTransferManager.verifyTransfer.call(account_investor2, account_investor1, web3.utils.toWei('1', 'ether'), 0, false) + // enum Result {INVALID, NA, VALID, FORCE_VALID} and we want VALID so it should be 2 + assert.equal(result.toString(), '0') + + + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should allow the transfer of tokens in a lockup if a period has passed", async() => { + + // wait 4 seconds + await new Promise(resolve => setTimeout(resolve, 4000)); + + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('3', 'ether'), { from: account_investor2 }); + }); + + it("Should prevent the transfer of tokens if the amount is larger than the amount allowed by lockups", async() => { + + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('4', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should allow the transfer of more tokens in a lockup if another period has passed", async() => { + + // wait 4 more seconds + await new Promise(resolve => setTimeout(resolve, 4000)); + + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('3', 'ether'), { from: account_investor2 }); + }); + + it("Should allow the transfer of all tokens in a lockup if the entire lockup has passed", async() => { + + let balance = await I_SecurityToken.balanceOf(account_investor2) + + // wait 4 more seconds + await new Promise(resolve => setTimeout(resolve, 4000)); + + await I_SecurityToken.transfer(account_investor1, balance, { from: account_investor2 }); + }); + + it("Should prevent the transfer of tokens in an edited lockup", async() => { + + + // balance here should be 12000000000000000000 (12e18 or 12 eth) + let balance = await I_SecurityToken.balanceOf(account_investor1) + + // create a lockup for their entire balance + // over 16 seconds total, with 4 periods of 4 seconds each. + await I_VolumeRestrictionTransferManager.addLockUp(account_investor1, 16, 4, 0, balance, { from: token_owner }); + + // let blockNumber = await web3.eth.getBlockNumber(); + // console.log('blockNumber',blockNumber) + let now = (await web3.eth.getBlock('latest')).timestamp + + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // check and get the lockup + let lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor1); + assert.equal(lockUpCount, 1) + + let lockUp = await I_VolumeRestrictionTransferManager.getLockUp(account_investor1, 0); + // console.log(lockUp); + // elements in lockup array are uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount + assert.equal(lockUp[0].toString(), '16'); + assert.equal(lockUp[1].toString(), '4'); + assert.equal(lockUp[2].toNumber(), now); + assert.equal(lockUp[3].toString(), balance.toString()); + + // edit the lockup + await I_VolumeRestrictionTransferManager.modifyLockUp(account_investor1, 0, 8, 4, 0, balance, { from: token_owner }); + + // attempt a transfer + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('6', 'ether'), { from: account_investor1 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + + // wait 4 seconds + await new Promise(resolve => setTimeout(resolve, 4000)); + + // transfer should succeed + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('6', 'ether'), { from: account_investor1 }); + + }); + + it("Should be possible to remove a lockup", async() => { + + let acct1Balance = await I_SecurityToken.balanceOf(account_investor1) + + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, acct1Balance, { from: account_investor1 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // check and get the lockup + let lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor1); + assert.equal(lockUpCount, 1) + + // remove the lockup + await I_VolumeRestrictionTransferManager.removeLockUp(account_investor1, 0, { from: token_owner }); + + lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor1); + assert.equal(lockUpCount, 0) + + let acct2BalanceBefore = await I_SecurityToken.balanceOf(account_investor2) + await I_SecurityToken.transfer(account_investor2, acct1Balance, { from: account_investor1 }); + let acct2BalanceAfter = await I_SecurityToken.balanceOf(account_investor2) + + assert.equal(acct2BalanceAfter.sub(acct2BalanceBefore).toString(), acct1Balance.toString()) + }); + + it("Should be possible to create multiple lockups at once", async() => { + + let balancesBefore = {} + + // should be 12000000000000000000 + balancesBefore[account_investor2] = await I_SecurityToken.balanceOf(account_investor2) + + + // should be 10000000000000000000 + balancesBefore[account_investor3] = await I_SecurityToken.balanceOf(account_investor3) + + + let lockUpCountsBefore = {} + + // get lockups for acct 2 + lockUpCountsBefore[account_investor2] = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); + assert.equal(lockUpCountsBefore[account_investor2], 1) // there's one old, expired lockup on acct already + + // get lockups for acct 3 + lockUpCountsBefore[account_investor3] = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor3); + assert.equal(lockUpCountsBefore[account_investor3], 0) + + // create lockups for their entire balances + await I_VolumeRestrictionTransferManager.addLockUpMulti( + [account_investor2, account_investor3], + [24, 8], + [4, 4], + [0, 0], + [balancesBefore[account_investor2], balancesBefore[account_investor3]], + { from: token_owner } + ); + + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor3 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + let balancesAfter = {} + balancesAfter[account_investor2] = await I_SecurityToken.balanceOf(account_investor2) + assert.equal(balancesBefore[account_investor2].toString(), balancesAfter[account_investor2].toString()) + + balancesAfter[account_investor3] = await I_SecurityToken.balanceOf(account_investor3) + assert.equal(balancesBefore[account_investor3].toString(), balancesAfter[account_investor3].toString()) + + let lockUpCountsAfter = {} + + // get lockups for acct 2 + lockUpCountsAfter[account_investor2] = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); + assert.equal(lockUpCountsAfter[account_investor2], 2); + + // get lockups for acct 3 + lockUpCountsAfter[account_investor3] = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor3); + assert.equal(lockUpCountsAfter[account_investor3], 1); + + // wait 4 seconds + await new Promise(resolve => setTimeout(resolve, 4000)); + + // try transfers again + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor3 }); + + + balancesAfter[account_investor2] = await I_SecurityToken.balanceOf(account_investor2) + assert.equal(balancesBefore[account_investor2].sub(web3.utils.toWei('2', 'ether')).toString(), balancesAfter[account_investor2].toString()) + + balancesAfter[account_investor3] = await I_SecurityToken.balanceOf(account_investor3) + assert.equal(balancesBefore[account_investor3].sub(web3.utils.toWei('5', 'ether')).toString(), balancesAfter[account_investor3].toString()) + + }); + + it("Should revert if the parameters are bad when creating multiple lockups", async() => { + let errorThrown = false; + try { + // pass in the wrong number of params. txn should revert + await I_VolumeRestrictionTransferManager.addLockUpMulti( + [account_investor2, account_investor3], + [16, 8], + [2], // this array should have 2 elements but it has 1, which should cause a revert + [0, 0], + [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], + { from: token_owner } + ); + } catch(error) { + console.log(` tx revert -> passed in wrong number of array elements`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should be possible to create a lockup with a specific start time in the future", async() => { + + // remove all lockups for account 2 + let lockUpsLength = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); + assert.equal(lockUpsLength, 2); + await I_VolumeRestrictionTransferManager.removeLockUp(account_investor2, 0, { from: token_owner }); + await I_VolumeRestrictionTransferManager.removeLockUp(account_investor2, 0, { from: token_owner }); + lockUpsLength = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); + assert.equal(lockUpsLength, 0); + + let now = (await web3.eth.getBlock('latest')).timestamp + + // balance here should be 10000000000000000000 + let balance = await I_SecurityToken.balanceOf(account_investor2) + + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 100, 10, now + 4, balance, { from: token_owner }); + + // try a transfer. it should fail because the lockup hasn't started yet. + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + now = (await web3.eth.getBlock('latest')).timestamp + + // wait 4 seconds for the lockup to begin + await new Promise(resolve => setTimeout(resolve, 4000)); + + // try another transfer. it should also fail because the lockup has just begun + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + now = (await web3.eth.getBlock('latest')).timestamp + + assert.ok(errorThrown, message); + + }); + + it("Should be possible to edit a lockup with a specific start time in the future", async() => { + + // edit the lockup + let now = (await web3.eth.getBlock('latest')).timestamp + + // should be 10000000000000000000 + let balance = await I_SecurityToken.balanceOf(account_investor2) + + // check and get the lockup + let lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); + assert.equal(lockUpCount, 1) + + let lockUp = await I_VolumeRestrictionTransferManager.getLockUp(account_investor2, 0); + + // elements in lockup array are uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount + assert.equal(lockUp[0].toString(), '100'); + assert.equal(lockUp[1].toString(), '10'); + assert.isAtMost(lockUp[2].toNumber(), now); + assert.equal(lockUp[3].toString(), balance.toString()); + + // edit the lockup + await I_VolumeRestrictionTransferManager.modifyLockUp(account_investor2, 0, 8, 4, now + 4, balance, { from: token_owner }); + + // check and get the lockup again + lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); + assert.equal(lockUpCount, 1) + + lockUp = await I_VolumeRestrictionTransferManager.getLockUp(account_investor2, 0); + + // elements in lockup array are uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount + assert.equal(lockUp[0].toString(), '8'); + assert.equal(lockUp[1].toString(), '4'); + assert.isAtMost(lockUp[2].toNumber(), now + 4); + assert.equal(lockUp[3].toString(), balance.toString()); + + // try a transfer. it should fail because again, the lockup hasn't started yet. + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // wait 4 seconds for the lockup to begin + await new Promise(resolve => setTimeout(resolve, 4000)); + + // try another transfer. it should fail because the lockup has just begun + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // wait 4 seconds for the lockup's first period to elapse + await new Promise(resolve => setTimeout(resolve, 4000)); + + // try another transfer. it should pass + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor2 }); + + + // try another transfer without waiting for another period to pass. it should fail + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // wait 4 seconds for the lockup's first period to elapse + await new Promise(resolve => setTimeout(resolve, 4000)); + + let lockUpBeforeVerify = await I_VolumeRestrictionTransferManager.getLockUp(account_investor2, 0); + // check if transfer will pass in read-only operation + let result = await I_VolumeRestrictionTransferManager.verifyTransfer.call(account_investor2, account_investor1, web3.utils.toWei('5', 'ether'), 0, false) + // enum Result {INVALID, NA, VALID, FORCE_VALID} and we want VALID so it should be 2 + assert.equal(result.toString(), '2') + let lockUpAfterVerify = await I_VolumeRestrictionTransferManager.getLockUp(account_investor2, 0); + + assert.equal(lockUpBeforeVerify[4].toString(), lockUpAfterVerify[4].toString()) + + // try another transfer. it should pass + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor2 }); + + // wait 4 seconds for the lockup's first period to elapse. but, we are all out of periods. + await new Promise(resolve => setTimeout(resolve, 4000)); + + // try one final transfer. this should fail because the user has already withdrawn their entire balance + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should be possible to stack lockups", async() => { + // should be 17000000000000000000 + let balance = await I_SecurityToken.balanceOf(account_investor1) + + // check and make sure that acct1 has no lockups so far + let lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor1); + assert.equal(lockUpCount.toString(), 0) + + await I_VolumeRestrictionTransferManager.addLockUp(account_investor1, 12, 4, 0, web3.utils.toWei('6', 'ether'), { from: token_owner }); + + // try to transfer 11 tokens that aren't locked up yet be locked up. should succeed + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('11', 'ether'), { from: account_investor1 }); + + // try a transfer. it should fail because it's locked up from the first lockups + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // wait 4 seconds for the lockup's first period to elapse. + await new Promise(resolve => setTimeout(resolve, 4000)); + + // should succeed + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); + + // send 8 back to investor1 so that we can lock them up + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('8', 'ether'), { from: account_investor2 }); + + // let's add another lockup to stack them + await I_VolumeRestrictionTransferManager.addLockUp(account_investor1, 16, 4, 0, web3.utils.toWei('8', 'ether'), { from: token_owner }); + + // try a transfer. it should fail because it's locked up from both lockups + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // wait 4 seconds for the 1st lockup's second period to elapse, and the 2nd lockup's first period to elapse + await new Promise(resolve => setTimeout(resolve, 4000)); + + // should now be able to transfer 4, because of 2 allowed from the 1st lockup and 2 from the 2nd + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); + + // try aother transfer. it should fail because it's locked up from both lockups again + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // wait 4 seconds for the 1st lockup's final period to elapse, and the 2nd lockup's second period to elapse + await new Promise(resolve => setTimeout(resolve, 4000)); + + // should now be able to transfer 4, because of 2 allowed from the 1st lockup and 2 from the 2nd + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); + + // try aother transfer. it should fail because it's locked up from both lockups again + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + } catch(error) { + console.log(` tx revert -> couldn't transfer because of lock up`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + + // wait 8 seconds for 2nd lockup's third and fourth periods to elapse + await new Promise(resolve => setTimeout(resolve, 8000)); + + // should now be able to transfer 4, because there are 2 allowed per period in the 2nd lockup, and 2 periods have elapsed + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); + + // send the 3 back from acct2 that we sent over in the beginning of this test + await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('3', 'ether'), { from: account_investor2 }); + + // try another transfer. it should pass because both lockups have been entirely used + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + + balance = await I_SecurityToken.balanceOf(account_investor1) + assert.equal(balance.toString(), web3.utils.toWei('2', 'ether')) + }); + + + it("Should get configuration function signature", async() => { + let sig = await I_VolumeRestrictionTransferManager.getInitFunction.call(); + assert.equal(web3.utils.hexToNumber(sig), 0); + }); + + + it("Should get the permission", async() => { + let perm = await I_VolumeRestrictionTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + // console.log(web3.utils.toAscii(perm[0]).replace(/\u0000/g, '')) + assert.equal(web3.utils.toAscii(perm[0]).replace(/\u0000/g, ''), "ADMIN") + }); + + }); + + describe("VolumeRestriction Transfer Manager Factory test cases", async() => { + + it("Should get the exact details of the factory", async() => { + assert.equal(await I_VolumeRestrictionTransferManagerFactory.setupCost.call(),0); + assert.equal((await I_VolumeRestrictionTransferManagerFactory.getTypes.call())[0],2); + assert.equal(web3.utils.toAscii(await I_VolumeRestrictionTransferManagerFactory.getName.call()) + .replace(/\u0000/g, ''), + "VolumeRestrictionTransferManager", + "Wrong Module added"); + assert.equal(await I_VolumeRestrictionTransferManagerFactory.getDescription.call(), + "Manage transfers using lock ups over time", + "Wrong Module added"); + assert.equal(await I_VolumeRestrictionTransferManagerFactory.getTitle.call(), + "Volume Restriction Transfer Manager", + "Wrong Module added"); + assert.equal(await I_VolumeRestrictionTransferManagerFactory.getInstructions.call(), + "Allows an issuer to set lockup periods for user addresses, with funds distributed over time. Init function takes no parameters.", + "Wrong Module added"); + + }); + + it("Should get the tags of the factory", async() => { + let tags = await I_VolumeRestrictionTransferManagerFactory.getTags.call(); + assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "Volume"); + }); + }); + +}); diff --git a/yarn.lock b/yarn.lock index 383b65c54..a8bd158f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,6 @@ # yarn lockfile v1 -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@sindresorhus/is@^0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" - "@soldoc/markdown@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@soldoc/markdown/-/markdown-0.1.0.tgz#9f85be75049af9721b5129f133d52dafbf5f671e" @@ -134,10 +123,6 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" -ansi-escapes@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -160,14 +145,6 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - -any-observable@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" - any-promise@1.3.0, any-promise@^1.0.0, any-promise@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -228,10 +205,6 @@ arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - array-extended@~0.0.3, array-extended@~0.0.4, array-extended@~0.0.5: version "0.0.11" resolved "https://registry.yarnpkg.com/array-extended/-/array-extended-0.0.11.tgz#d7144ae748de93ca726f121009dbff1626d164bd" @@ -262,7 +235,7 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" -arrify@^1.0.0, arrify@^1.0.1: +arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -296,14 +269,6 @@ assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" -ast-types@0.10.1: - version "0.10.1" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd" - -ast-types@0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.3.tgz#c20757fe72ee71278ea0ff3d87e5c2ca30d9edf8" - async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -324,11 +289,11 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" -async@1.x, async@^1.4.0, async@^1.4.2, async@^1.5.0, async@~1.5.2: +async@1.x, async@^1.4.0, async@^1.4.2, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.0: +async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0: version "2.6.0" resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" dependencies: @@ -571,10 +536,6 @@ babel-plugin-syntax-async-generators@^6.5.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" -babel-plugin-syntax-class-constructor-call@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" - babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" @@ -591,14 +552,6 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -babel-plugin-syntax-export-extensions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" - -babel-plugin-syntax-flow@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" @@ -623,14 +576,6 @@ babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async- babel-plugin-syntax-async-functions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-class-constructor-call@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" - dependencies: - babel-plugin-syntax-class-constructor-call "^6.18.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-plugin-transform-class-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" @@ -835,20 +780,6 @@ babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-e babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-export-extensions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" - dependencies: - babel-plugin-syntax-export-extensions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-flow-strip-types@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.22.0" - babel-plugin-transform-object-rest-spread@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" @@ -912,7 +843,7 @@ babel-preset-env@^1.3.2: invariant "^2.2.2" semver "^5.3.0" -babel-preset-es2015@6.24.1, babel-preset-es2015@^6.9.0: +babel-preset-es2015@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" dependencies: @@ -941,15 +872,7 @@ babel-preset-es2015@6.24.1, babel-preset-es2015@^6.9.0: babel-plugin-transform-es2015-unicode-regex "^6.24.1" babel-plugin-transform-regenerator "^6.24.1" -babel-preset-stage-1@^6.5.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0" - dependencies: - babel-plugin-transform-class-constructor-call "^6.24.1" - babel-plugin-transform-export-extensions "^6.22.0" - babel-preset-stage-2 "^6.24.1" - -babel-preset-stage-2@6.24.1, babel-preset-stage-2@^6.24.1: +babel-preset-stage-2@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" dependencies: @@ -968,7 +891,7 @@ babel-preset-stage-3@6.24.1, babel-preset-stage-3@^6.24.1: babel-plugin-transform-exponentiation-operator "^6.24.1" babel-plugin-transform-object-rest-spread "^6.22.0" -babel-register@6.26.0, babel-register@^6.26.0, babel-register@^6.9.0: +babel-register@6.26.0, babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" dependencies: @@ -1027,14 +950,10 @@ babelify@^7.3.0: babel-core "^6.0.14" object-assign "^4.0.0" -babylon@^6.17.3, babylon@^6.18.0: +babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" -babylon@^7.0.0-beta.30: - version "7.0.0-beta.46" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.46.tgz#b6ddaba81bbb130313932757ff9c195d527088b6" - balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -1107,10 +1026,6 @@ binary-extensions@^1.0.0: version "1.11.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" -binaryextensions@2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935" - bindings@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" @@ -1426,22 +1341,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cacheable-request@^2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" - dependencies: - clone-response "1.0.2" - get-stream "3.0.0" - http-cache-semantics "3.8.1" - keyv "3.0.0" - lowercase-keys "1.0.0" - normalize-url "2.0.1" - responselike "1.0.2" - -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -1486,7 +1385,7 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1496,7 +1395,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -1504,14 +1403,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.3 escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -1590,35 +1481,12 @@ cli-color@^1.2.0: memoizee "^0.4.3" timers-ext "0.1" -cli-cursor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" - dependencies: - restore-cursor "^1.0.1" - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" dependencies: restore-cursor "^2.0.0" -cli-spinners@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" - -cli-table@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" - dependencies: - colors "1.0.3" - -cli-truncate@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" - dependencies: - slice-ansi "0.0.4" - string-width "^1.0.1" - cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -1647,44 +1515,14 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" -clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - -clone-response@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - dependencies: - mimic-response "^1.0.0" - -clone-stats@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" - -clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - clone@2.x: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" -clone@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - clone@^2.0.0, clone@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" -cloneable-readable@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" - dependencies: - inherits "^2.0.1" - process-nextick-args "^2.0.0" - readable-stream "^2.3.5" - co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -1717,7 +1555,7 @@ color-name@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" -colors@1.0.3, colors@1.0.x: +colors@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" @@ -1753,10 +1591,6 @@ commander@~2.8.1: dependencies: graceful-readlink ">= 1.0.0" -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - compare-versions@^3.0.1: version "3.3.0" resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.0.tgz#af93ea705a96943f622ab309578b9b90586f39c3" @@ -1828,10 +1662,6 @@ core-js@^2.4.0, core-js@^2.5.0: version "2.5.3" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" -core-js@^2.4.1: - version "2.5.6" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.6.tgz#0fe6d45bf3cac3ac364a9d72de7576f4eb221b9d" - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1896,16 +1726,6 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - cryptiles@3.x.x: version "3.1.2" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" @@ -1954,10 +1774,6 @@ d@1: dependencies: es5-ext "^0.10.9" -dargs@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829" - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1972,18 +1788,10 @@ date-extended@~0.0.3: extended "~0.0.3" is-extended "~0.0.3" -date-fns@^1.27.2: - version "1.29.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" - date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -dateformat@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - death@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" @@ -2163,10 +1971,6 @@ destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" -detect-conflict@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e" - detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" @@ -2181,7 +1985,7 @@ diff@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" -diff@3.5.0, diff@^3.3.1, diff@^3.5.0: +diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -2193,13 +1997,6 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" -dir-glob@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" - dependencies: - arrify "^1.0.1" - path-type "^3.0.0" - doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -2253,18 +2050,10 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -ejs@^2.5.9: - version "2.6.1" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" - electron-to-chromium@^1.3.45: version "1.3.45" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.45.tgz#458ac1b1c5c760ce8811a16d2bfbd97ec30bafb8" -elegant-spinner@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" - elliptic@6.3.3: version "6.3.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" @@ -2324,37 +2113,18 @@ enhanced-resolve@^3.4.0: object-assign "^4.0.1" tapable "^0.2.7" -enhanced-resolve@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a" - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - -envinfo@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-4.4.2.tgz#472c49f3a8b9bca73962641ce7cb692bf623cd1c" - errno@^0.1.3, errno@~0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" dependencies: prr "~1.0.1" -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: is-arrayish "^0.2.1" -error@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" - dependencies: - string-template "~0.2.1" - xtend "~4.0.0" - es-abstract@^1.5.0: version "1.11.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681" @@ -2568,7 +2338,7 @@ esprima@2.7.x, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" -esprima@^4.0.0, esprima@~4.0.0: +esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" @@ -2708,7 +2478,7 @@ ethereumjs-abi@0.6.4: bn.js "^4.10.0" ethereumjs-util "^4.3.0" -"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": +ethereumjs-abi@^0.6.5, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": version "0.6.5" resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf" dependencies: @@ -2880,10 +2650,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -2908,12 +2674,6 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - dependencies: - homedir-polyfill "^1.0.1" - express@^4.14.0: version "4.16.3" resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" @@ -2988,7 +2748,7 @@ extendr@^2.1.0: dependencies: typechecker "~2.0.1" -external-editor@^2.0.4, external-editor@^2.1.0: +external-editor@^2.0.4: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: @@ -3056,16 +2816,6 @@ fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" -fast-glob@^2.0.2: - version "2.2.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.1.tgz#686c2345be88f3741e174add0be6f2e5b6078889" - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.1" - micromatch "^3.1.10" - fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -3098,13 +2848,6 @@ fetch-ponyfill@^4.0.0: dependencies: node-fetch "~1.7.1" -figures@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -3178,12 +2921,6 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -first-chunk-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" - dependencies: - readable-stream "^2.0.2" - flat-cache@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" @@ -3193,10 +2930,6 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-parser@^0.*: - version "0.72.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.72.0.tgz#6c8041e76ac7d0be1a71ce29c00cd1435fb6013c" - for-each@^0.3.2, for-each@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" @@ -3243,13 +2976,6 @@ fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" -from2@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" @@ -3330,12 +3056,11 @@ functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" -ganache-cli@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.1.0.tgz#486c846497204b644166b5f0f74c9b41d02bdc25" +ganache-cli@^6.1.8: + version "6.1.8" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.1.8.tgz#49a8a331683a9652183f82ef1378d17e1814fcd3" dependencies: source-map-support "^0.5.3" - webpack-cli "^2.0.9" gauge@~2.7.3: version "2.7.4" @@ -3354,10 +3079,6 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" -get-stream@3.0.0, get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - get-stream@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" @@ -3365,6 +3086,10 @@ get-stream@^2.2.0: object-assign "^4.0.1" pinkie-promise "^2.0.0" +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -3375,26 +3100,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -gh-got@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0" - dependencies: - got "^7.0.0" - is-plain-obj "^1.1.0" - -github-username@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417" - dependencies: - gh-got "^6.0.0" - -glob-all@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" - dependencies: - glob "^7.0.5" - yargs "~1.2.6" - glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -3415,10 +3120,6 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" @@ -3450,24 +3151,6 @@ glob@~6.0.4: once "^1.3.0" path-is-absolute "^1.0.0" -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - global@~4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" @@ -3494,19 +3177,7 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^8.0.0, globby@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" - dependencies: - array-union "^1.0.1" - dir-glob "^2.0.0" - fast-glob "^2.0.2" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - -got@7.1.0, got@^7.0.0, got@^7.1.0: +got@7.1.0, got@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" dependencies: @@ -3525,29 +3196,7 @@ got@7.1.0, got@^7.0.0, got@^7.1.0: url-parse-lax "^1.0.0" url-to-options "^1.0.1" -got@^8.2.0: - version "8.3.1" - resolved "https://registry.yarnpkg.com/got/-/got-8.3.1.tgz#093324403d4d955f5a16a7a8d39955d055ae10ed" - dependencies: - "@sindresorhus/is" "^0.7.0" - cacheable-request "^2.1.1" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - into-stream "^3.1.0" - is-retry-allowed "^1.1.0" - isurl "^1.0.0-alpha5" - lowercase-keys "^1.0.0" - mimic-response "^1.0.0" - p-cancelable "^0.4.0" - p-timeout "^2.0.1" - pify "^3.0.0" - safe-buffer "^5.1.1" - timed-out "^4.0.1" - url-parse-lax "^3.0.0" - url-to-options "^1.0.1" - -graceful-fs@*, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@*, graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -3555,16 +3204,14 @@ graceful-fs@*, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, gra version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" -grouped-queue@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c" - dependencies: - lodash "^4.17.2" - growl@1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + handlebars@^4.0.1: version "4.0.11" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" @@ -3599,10 +3246,6 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" @@ -3715,20 +3358,10 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -homedir-polyfill@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" - dependencies: - parse-passwd "^1.0.0" - hosted-git-info@^2.1.4: version "2.6.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222" -http-cache-semantics@3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - http-errors@1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" @@ -3798,7 +3431,7 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.3.3, ignore@^3.3.5, ignore@^3.3.6: +ignore@^3.3.3, ignore@^3.3.6: version "3.3.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b" @@ -3817,27 +3450,10 @@ immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" -import-local@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" - dependencies: - pkg-dir "^2.0.0" - resolve-cwd "^2.0.0" - imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" @@ -3857,7 +3473,7 @@ inherits@2.0.1, inherits@=2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" -ini@^1.3.4, ini@~1.3.0: +ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -3880,35 +3496,10 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@^5.1.0, inquirer@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.1.0" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^5.5.2" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -interpret@^1.0.0, interpret@^1.0.4: +interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" -into-stream@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" - dependencies: - from2 "^2.1.1" - p-is-promise "^1.1.0" - invariant@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" @@ -4105,12 +3696,6 @@ is-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" -is-observable@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" - dependencies: - symbol-observable "^0.2.2" - is-odd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" @@ -4133,7 +3718,7 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: +is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -4165,16 +3750,10 @@ is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" -is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: +is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" -is-scoped@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-scoped/-/is-scoped-1.0.0.tgz#449ca98299e713038256289ecb2b540dc437cb30" - dependencies: - scoped-regex "^1.0.0" - is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4191,7 +3770,7 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" -is-windows@^1.0.1, is-windows@^1.0.2: +is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4203,10 +3782,6 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isbinaryfile@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -4251,14 +3826,6 @@ istanbul@^0.4.5: which "^1.1.1" wordwrap "^1.0.0" -istextorbinary@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.2.1.tgz#a5231a08ef6dd22b268d0895084cf8d58b5bec53" - dependencies: - binaryextensions "2" - editions "^1.3.3" - textextensions "2" - isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" @@ -4301,46 +3868,6 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" -jscodeshift@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.4.1.tgz#da91a1c2eccfa03a3387a21d39948e251ced444a" - dependencies: - async "^1.5.0" - babel-plugin-transform-flow-strip-types "^6.8.0" - babel-preset-es2015 "^6.9.0" - babel-preset-stage-1 "^6.5.0" - babel-register "^6.9.0" - babylon "^6.17.3" - colors "^1.1.2" - flow-parser "^0.*" - lodash "^4.13.1" - micromatch "^2.3.7" - node-dir "0.1.8" - nomnom "^1.8.1" - recast "^0.12.5" - temp "^0.8.1" - write-file-atomic "^1.2.0" - -jscodeshift@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.5.0.tgz#bdb7b6cc20dd62c16aa728c3fa2d2fe66ca7c748" - dependencies: - babel-plugin-transform-flow-strip-types "^6.8.0" - babel-preset-es2015 "^6.9.0" - babel-preset-stage-1 "^6.5.0" - babel-register "^6.9.0" - babylon "^7.0.0-beta.30" - colors "^1.1.2" - flow-parser "^0.*" - lodash "^4.13.1" - micromatch "^2.3.7" - neo-async "^2.5.0" - node-dir "0.1.8" - nomnom "^1.8.1" - recast "^0.14.1" - temp "^0.8.1" - write-file-atomic "^1.2.0" - jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -4349,18 +3876,10 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - json-loader@^0.5.4: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - json-rpc-engine@^3.6.0: version "3.6.3" resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.6.3.tgz#df80459da8bc9020bfb5372b3b70e6c20ea07d40" @@ -4455,12 +3974,6 @@ keccakjs@^0.2.0, keccakjs@^0.2.1: browserify-sha3 "^0.0.1" sha3 "^1.1.0" -keyv@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" - dependencies: - json-buffer "3.0.0" - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4552,54 +4065,6 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -listr-silent-renderer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" - -listr-update-renderer@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" - dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - elegant-spinner "^1.0.1" - figures "^1.7.0" - indent-string "^3.0.0" - log-symbols "^1.0.2" - log-update "^1.0.2" - strip-ansi "^3.0.1" - -listr-verbose-renderer@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" - dependencies: - chalk "^1.1.3" - cli-cursor "^1.0.2" - date-fns "^1.27.2" - figures "^1.7.0" - -listr@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d" - dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - figures "^1.7.0" - indent-string "^2.1.0" - is-observable "^0.2.0" - is-promise "^2.1.0" - is-stream "^1.1.0" - listr-silent-renderer "^1.1.1" - listr-update-renderer "^0.4.0" - listr-verbose-renderer "^0.4.0" - log-symbols "^1.0.2" - log-update "^1.0.2" - ora "^0.2.3" - p-map "^1.1.1" - rxjs "^5.4.2" - stream-to-observable "^0.2.0" - strip-ansi "^3.0.1" - load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -4619,15 +4084,6 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" @@ -4651,7 +4107,7 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" -lodash@4.x, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.5, lodash@^4.3.0: +lodash@4.x, lodash@^4.14.0, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.5, lodash@^4.3.0: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" @@ -4667,25 +4123,6 @@ log-driver@^1.2.5: version "1.2.7" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" -log-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" - dependencies: - chalk "^1.0.0" - -log-symbols@^2.1.0, log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - dependencies: - chalk "^2.0.1" - -log-update@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" - dependencies: - ansi-escapes "^1.0.0" - cli-cursor "^1.0.2" - long-timeout@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/long-timeout/-/long-timeout-0.1.1.tgz#9721d788b47e0bcb5a24c2e2bee1a0da55dab514" @@ -4706,10 +4143,6 @@ loose-envify@^1.1.0, loose-envify@^1.3.1: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lowercase-keys@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - lowercase-keys@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -4731,7 +4164,7 @@ ltgt@~2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" -make-dir@^1.0.0, make-dir@^1.1.0: +make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" dependencies: @@ -4774,30 +4207,6 @@ media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" -mem-fs-editor@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-4.0.2.tgz#55a79b1e824da631254c4c95ba6366602c77af90" - dependencies: - commondir "^1.0.1" - deep-extend "^0.5.1" - ejs "^2.5.9" - glob "^7.0.3" - globby "^8.0.0" - isbinaryfile "^3.0.2" - mkdirp "^0.5.0" - multimatch "^2.0.0" - rimraf "^2.2.8" - through2 "^2.0.0" - vinyl "^2.0.1" - -mem-fs@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc" - dependencies: - through2 "^2.0.0" - vinyl "^1.1.0" - vinyl-file "^2.0.0" - mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" @@ -4843,10 +4252,6 @@ merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" -merge2@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.2.tgz#03212e3da8d86c4d8523cebd6318193414f94e34" - merkle-patricia-tree@^2.1.2: version "2.3.1" resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz#7d4e7263a9c85c1679187cad4a6d71f48d524c71" @@ -4874,7 +4279,7 @@ methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" -micromatch@^2.1.5, micromatch@^2.3.7: +micromatch@^2.1.5: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" dependencies: @@ -4892,7 +4297,7 @@ micromatch@^2.1.5, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.1.10, micromatch@^3.1.4: +micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" dependencies: @@ -4963,7 +4368,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -4973,10 +4378,6 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" - minimist@^1.2.0, minimist@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -5077,15 +4478,6 @@ multihashes@^0.4.5: bs58 "^4.0.1" varint "^5.0.0" -multimatch@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" - dependencies: - array-differ "^1.0.0" - array-union "^1.0.1" - arrify "^1.0.0" - minimatch "^3.0.0" - mustache@*, mustache@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.1.tgz#ef5db3c0d11f1640e9baa47f4e65ba0c3fcd82b9" @@ -5151,10 +4543,6 @@ next-tick@1: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" -nice-try@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" - node-async-loop@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/node-async-loop/-/node-async-loop-1.2.2.tgz#c5870299bf6477b780c88b431aa5b37733f55a3d" @@ -5166,10 +4554,6 @@ node-cache@^4.1.1: clone "2.x" lodash "4.x" -node-dir@0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d" - node-fetch@^1.0.1, node-fetch@~1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -5228,13 +4612,6 @@ node-schedule@^1.2.3: long-timeout "0.1.1" sorted-array-functions "^1.0.0" -nomnom@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" - dependencies: - chalk "~0.4.0" - underscore "~1.6.0" - nopt@3.x, nopt@~3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -5263,14 +4640,6 @@ normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-url@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" - dependencies: - prepend-http "^2.0.0" - query-string "^5.0.1" - sort-keys "^2.0.0" - npm-bundled@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" @@ -5385,10 +4754,6 @@ once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^1.0.0: - version "1.1.0" - resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" - onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -5417,15 +4782,6 @@ optionator@^0.8.1, optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -ora@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" - dependencies: - chalk "^1.1.1" - cli-cursor "^1.0.2" - cli-spinners "^0.1.2" - object-assign "^4.0.1" - original-require@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/original-require/-/original-require-1.0.1.tgz#0f130471584cd33511c5ec38c8d59213f9ac5e20" @@ -5467,28 +4823,10 @@ p-cancelable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" -p-cancelable@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" - -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - dependencies: - p-reduce "^1.0.0" - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" -p-is-promise@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" - -p-lazy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-1.0.0.tgz#ec53c802f2ee3ac28f166cc82d0b2b02de27a835" - p-limit@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" @@ -5501,26 +4839,12 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" -p-map@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" - -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - p-timeout@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" dependencies: p-finally "^1.0.0" -p-timeout@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" - dependencies: - p-finally "^1.0.0" - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -5561,17 +4885,6 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" @@ -5606,7 +4919,7 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" -path-key@^2.0.0, path-key@^2.0.1: +path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -5632,12 +4945,6 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - dependencies: - pify "^3.0.0" - pbkdf2@^3.0.3: version "3.0.16" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" @@ -5684,12 +4991,6 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - dependencies: - find-up "^2.1.0" - pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" @@ -5710,27 +5011,15 @@ prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@^1.5.3: - version "1.12.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325" - -pretty-bytes@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" - -private@^0.1.6, private@^0.1.7, private@^0.1.8, private@~0.1.5: +private@^0.1.6, private@^0.1.7, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" -process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: +process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -5896,13 +5185,6 @@ react@^16.2.0: object-assign "^4.1.1" prop-types "^15.6.0" -read-chunk@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655" - dependencies: - pify "^3.0.0" - safe-buffer "^5.1.1" - read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -5917,13 +5199,6 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -5940,14 +5215,6 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - readable-stream@^1.0.33: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -5957,7 +5224,7 @@ readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -5991,25 +5258,6 @@ readline-sync@^1.4.9: version "1.4.9" resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.9.tgz#3eda8e65f23cd2a17e61301b1f0003396af5ecda" -recast@^0.12.5: - version "0.12.9" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.12.9.tgz#e8e52bdb9691af462ccbd7c15d5a5113647a15f1" - dependencies: - ast-types "0.10.1" - core-js "^2.4.1" - esprima "~4.0.0" - private "~0.1.5" - source-map "~0.6.1" - -recast@^0.14.1: - version "0.14.7" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.14.7.tgz#4f1497c2b5826d42a66e8e3c9d80c512983ff61d" - dependencies: - ast-types "0.11.3" - esprima "~4.0.0" - private "~0.1.5" - source-map "~0.6.1" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -6089,14 +5337,6 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -replace-ext@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" - -replace-ext@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - req-cwd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-1.0.1.tgz#0d73aeae9266e697a78f7976019677e76acf0fff" @@ -6180,19 +5420,6 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - dependencies: - resolve-from "^3.0.0" - -resolve-dir@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" @@ -6201,10 +5428,6 @@ resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -6225,19 +5448,6 @@ resolve@~1.5.0: dependencies: path-parse "^1.0.5" -responselike@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - dependencies: - lowercase-keys "^1.0.0" - -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" - dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" - restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -6261,16 +5471,12 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.6.1, rimraf@^2.6.2: +rimraf@2, rimraf@^2.2.8, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: glob "^7.0.5" -rimraf@~2.2.6: - version "2.2.8" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" - ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -6282,7 +5488,7 @@ rlp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.0.0.tgz#9db384ff4b89a8f61563d92395d8625b18f3afb0" -run-async@^2.0.0, run-async@^2.2.0: +run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" dependencies: @@ -6302,12 +5508,6 @@ rx-lite@*, rx-lite@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" -rxjs@^5.4.2, rxjs@^5.5.2: - version "5.5.10" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.10.tgz#fde02d7a614f6c8683d0d1957827f492e09db045" - dependencies: - symbol-observable "1.0.1" - safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -6348,10 +5548,6 @@ scandirectory@^2.5.0: safefs "^3.1.2" taskgroup "^4.0.5" -scoped-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8" - scrypt-async@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/scrypt-async/-/scrypt-async-1.3.1.tgz#a11fd6fac981b4b823ee01dee0221169500ddae9" @@ -6520,7 +5716,7 @@ shelljs@^0.7.4: interpret "^1.0.0" rechoir "^0.6.2" -shelljs@^0.8.0, shelljs@^0.8.1, shelljs@^0.8.2: +shelljs@^0.8.1, shelljs@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.2.tgz#345b7df7763f4c2340d584abb532c5f752ca9e35" dependencies: @@ -6548,20 +5744,12 @@ slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - slice-ansi@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" dependencies: is-fullwidth-code-point "^2.0.0" -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -6638,9 +5826,9 @@ solc@^0.4.2: semver "^5.3.0" yargs "^4.7.1" -solidity-coverage@^0.5.5: - version "0.5.7" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.5.7.tgz#b7eb67678d446ab2702a26c2158ad71b4865a057" +solidity-coverage@^0.5.10: + version "0.5.11" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.5.11.tgz#1ee45f6d98b75a615aadb8f9aa7db4a2b32258e7" dependencies: death "^1.1.0" ethereumjs-testrpc-sc "6.1.6" @@ -6701,12 +5889,6 @@ solparse@2.2.5: pegjs "^0.10.0" yargs "^10.0.3" -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - dependencies: - is-plain-obj "^1.0.0" - sorted-array-functions@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/sorted-array-functions/-/sorted-array-functions-1.2.0.tgz#43265b21d6e985b7df31621b1c11cc68d8efc7c3" @@ -6852,12 +6034,6 @@ stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" -stream-to-observable@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10" - dependencies: - any-observable "^0.2.0" - strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -6871,10 +6047,6 @@ string-extended@0.0.8: extended "~0.0.3" is-extended "~0.0.3" -string-template@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" - string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -6924,17 +6096,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - -strip-bom-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca" - dependencies: - first-chunk-stream "^2.0.0" - strip-bom "^2.0.0" - strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -7011,14 +6172,6 @@ swarm-js@0.1.37: tar.gz "^1.0.5" xhr-request-promise "^0.1.2" -symbol-observable@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - -symbol-observable@^0.2.2: - version "0.2.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" - table@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -7034,10 +6187,6 @@ tapable@^0.2.7: version "0.2.8" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" -tapable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" - tape@^4.4.0, tape@^4.6.3: version "4.9.0" resolved "https://registry.yarnpkg.com/tape/-/tape-4.9.0.tgz#855c08360395133709d34d3fbf9ef341eb73ca6a" @@ -7105,21 +6254,10 @@ taskgroup@^4.0.5, taskgroup@^4.2.0: ambi "^2.2.0" csextends "^1.0.3" -temp@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" - dependencies: - os-tmpdir "^1.0.0" - rimraf "~2.2.6" - text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -textextensions@2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286" - thenify-all@^1.0.0, thenify-all@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" @@ -7132,13 +6270,6 @@ thenify-all@^1.0.0, thenify-all@^1.6.0: dependencies: any-promise "^1.0.0" -through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - through@^2.3.6, through@~2.3.4, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -7278,7 +6409,7 @@ truffle-wallet-provider@0.0.5: web3 "^0.18.2" web3-provider-engine "^8.4.0" -truffle@^4.1.11: +truffle@^4.1.13: version "4.1.14" resolved "https://registry.yarnpkg.com/truffle/-/truffle-4.1.14.tgz#8d2c298e29abf9b1e486e44ff9faca6d34bb9030" dependencies: @@ -7385,10 +6516,6 @@ underscore@^1.8.3: version "1.9.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" -underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" @@ -7417,10 +6544,6 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -untildify@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1" - upath@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.5.tgz#02cab9ecebe95bbec6d5fc2566325725ab6d1a73" @@ -7441,12 +6564,6 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - dependencies: - prepend-http "^2.0.0" - url-set-query@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" @@ -7506,10 +6623,6 @@ uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" -v8-compile-cache@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz#8d32e4f16974654657e676e0e467a348e89b0dc4" - valid-url@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" @@ -7537,36 +6650,6 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vinyl-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a" - dependencies: - graceful-fs "^4.1.2" - pify "^2.3.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - strip-bom-stream "^2.0.0" - vinyl "^1.1.0" - -vinyl@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - -vinyl@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c" - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" - vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" @@ -7881,43 +6964,6 @@ web3@^1.0.0-beta.33: web3-shh "1.0.0-beta.34" web3-utils "1.0.0-beta.34" -webpack-addons@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/webpack-addons/-/webpack-addons-1.1.5.tgz#2b178dfe873fb6e75e40a819fa5c26e4a9bc837a" - dependencies: - jscodeshift "^0.4.0" - -webpack-cli@^2.0.9: - version "2.1.3" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.1.3.tgz#65d166851abaa56067ef3f716b02a97ba6bbe84d" - dependencies: - chalk "^2.3.2" - cross-spawn "^6.0.5" - diff "^3.5.0" - enhanced-resolve "^4.0.0" - envinfo "^4.4.2" - glob-all "^3.1.0" - global-modules "^1.0.0" - got "^8.2.0" - import-local "^1.0.0" - inquirer "^5.1.0" - interpret "^1.0.4" - jscodeshift "^0.5.0" - listr "^0.13.0" - loader-utils "^1.1.0" - lodash "^4.17.5" - log-symbols "^2.2.0" - mkdirp "^0.5.1" - p-each-series "^1.0.0" - p-lazy "^1.0.0" - prettier "^1.5.3" - supports-color "^5.3.0" - v8-compile-cache "^1.1.2" - webpack-addons "^1.1.5" - yargs "^11.1.0" - yeoman-environment "^2.0.0" - yeoman-generator "^2.0.4" - webpack-sources@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" @@ -7973,7 +7019,7 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.1.1, which@^1.2.14, which@^1.2.9: +which@^1.1.1, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -8027,14 +7073,6 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^1.2.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" @@ -8088,7 +7126,7 @@ xregexp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -8156,7 +7194,7 @@ yargs@^10.0.3: y18n "^3.2.1" yargs-parser "^8.1.0" -yargs@^11.0.0, yargs@^11.1.0: +yargs@^11.0.0: version "11.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" dependencies: @@ -8210,12 +7248,6 @@ yargs@^8.0.2: y18n "^3.2.1" yargs-parser "^7.0.0" -yargs@~1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.2.6.tgz#9c7b4a82fd5d595b2bf17ab6dcc43135432fe34b" - dependencies: - minimist "^0.1.0" - yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" @@ -8231,53 +7263,3 @@ yauzl@^2.4.2: dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.0.1" - -yeoman-environment@^2.0.0, yeoman-environment@^2.0.5: - version "2.1.0" - resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.1.0.tgz#175f49ad693aff41c8998d32f6103c20c62ec37b" - dependencies: - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^3.1.0" - diff "^3.3.1" - escape-string-regexp "^1.0.2" - globby "^8.0.1" - grouped-queue "^0.3.3" - inquirer "^5.2.0" - is-scoped "^1.0.0" - lodash "^4.17.10" - log-symbols "^2.1.0" - mem-fs "^1.1.0" - strip-ansi "^4.0.0" - text-table "^0.2.0" - untildify "^3.0.2" - -yeoman-generator@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-2.0.5.tgz#57b0b3474701293cc9ec965288f3400b00887c81" - dependencies: - async "^2.6.0" - chalk "^2.3.0" - cli-table "^0.3.1" - cross-spawn "^6.0.5" - dargs "^5.1.0" - dateformat "^3.0.3" - debug "^3.1.0" - detect-conflict "^1.0.0" - error "^7.0.2" - find-up "^2.1.0" - github-username "^4.0.0" - istextorbinary "^2.2.1" - lodash "^4.17.10" - make-dir "^1.1.0" - mem-fs-editor "^4.0.0" - minimist "^1.2.0" - pretty-bytes "^4.0.2" - read-chunk "^2.1.0" - read-pkg-up "^3.0.0" - rimraf "^2.6.2" - run-async "^2.0.0" - shelljs "^0.8.0" - text-table "^0.2.0" - through2 "^2.0.0" - yeoman-environment "^2.0.5" From 1f29ca9d7c3fc057874938c2c5ee4e71f8e7b85c Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 14:08:34 +0530 Subject: [PATCH 075/142] Decimals fixed for percentage --- contracts/modules/TransferManager/PercentageTransferManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/modules/TransferManager/PercentageTransferManager.sol b/contracts/modules/TransferManager/PercentageTransferManager.sol index 0e67539af..de5b590a3 100644 --- a/contracts/modules/TransferManager/PercentageTransferManager.sol +++ b/contracts/modules/TransferManager/PercentageTransferManager.sol @@ -45,7 +45,7 @@ contract PercentageTransferManager is ITransferManager { return Result.NA; } uint256 newBalance = ISecurityToken(securityToken).balanceOf(_to).add(_amount); - if (newBalance.mul(10**uint256(ISecurityToken(securityToken).decimals())).div(ISecurityToken(securityToken).totalSupply()) > maxHolderPercentage) { + if (newBalance.mul(uint256(10)**18).div(ISecurityToken(securityToken).totalSupply()) > maxHolderPercentage) { return Result.INVALID; } return Result.NA; From 6e9bcc43bd579949280dd04b812f215dc02801a8 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 14:38:56 +0530 Subject: [PATCH 076/142] more improvement into the createInstances --- test/e_erc20_dividends.js | 1 - test/f_ether_dividends.js | 1 - test/h_general_transfer_manager.js | 163 ++++++----------------------- test/helpers/createInstances.js | 57 ++++++++++ 4 files changed, 89 insertions(+), 133 deletions(-) diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 7b67bc414..c4fae1fc9 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -6,7 +6,6 @@ import { setUpPolymathNetwork } from "./helpers/createInstances"; const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpointFactory.sol"); const ERC20DividendCheckpoint = artifacts.require("./ERC20DividendCheckpoint"); const Web3 = require("web3"); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 215b2deba..a8cccad0a 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -7,7 +7,6 @@ import { setUpPolymathNetwork } from "./helpers/createInstances"; const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); const EtherDividendCheckpoint = artifacts.require("./EtherDividendCheckpoint"); const Web3 = require("web3"); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 65fc82c21..d5a8b3e03 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -1,26 +1,17 @@ import latestTime from "./helpers/latestTime"; -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { signData } from "./helpers/signData"; import { pk } from "./helpers/testprivateKey"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed } from "./helpers/createInstances"; + -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const DummySTO = artifacts.require("./DummySTO.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -87,8 +78,6 @@ contract("GeneralTransferManager", accounts => { const cap = web3.utils.toWei("10", "ether"); const someString = "A string which is not used"; const STOParameters = ["uint256", "uint256", "uint256", "string"]; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; before(async () => { // Accounts setup @@ -106,127 +95,39 @@ contract("GeneralTransferManager", accounts => { account_affiliates1 = accounts[3]; account_affiliates2 = accounts[4]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the DummySTOFactory - - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); + [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 0092b51d1..f6f797417 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -7,17 +7,24 @@ const SecurityToken = artifacts.require("./SecurityToken.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); +const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpointFactory.sol"); +const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); const STFactory = artifacts.require("./STFactory.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); +const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const PolyToken = artifacts.require("./PolyToken.sol"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); +const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const Web3 = require("web3"); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port // Contract Instance Declaration +let I_EtherDividendCheckpointFactory; +let I_ERC20DividendCheckpointFactory; +let I_GeneralPermissionManagerFactory; let I_GeneralTransferManagerFactory; let I_GeneralTransferManager; let I_ModuleRegistryProxy; @@ -25,6 +32,7 @@ let I_ModuleRegistry; let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_SecurityToken; +let I_DummySTOFactory; let I_PolyToken; let I_STFactory; let I_PolymathRegistry; @@ -157,3 +165,52 @@ async function registerGTM(account_polymath) { await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); } + + + +export async function deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralPermissionManagerFactory contract was not deployed" + ); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + return new Array(I_GeneralPermissionManagerFactory); +} + + +export async function deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "DummySTOFactory contract was not deployed" + ); + + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + + return new Array(I_DummySTOFactory); +} + +export async function deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { + I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_ERC20DividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "DummySTOFactory contract was not deployed" + ); + + await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + + return new Array(I_ERC20DividendCheckpointFactory); +} \ No newline at end of file From 813777debfbdf1488f1c9fe2c0e891b7bba943ad Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 16:15:01 +0530 Subject: [PATCH 077/142] test attempt --- package-lock.json | 4395 ++++++++--------- test/w_volume_restriction_transfer_manager.js | 21 +- 2 files changed, 2204 insertions(+), 2212 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8cce7f884..2cace804d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,14 @@ "integrity": "sha1-JP/ukmQijhw+3WH9MWLWNYeVSTM=", "dev": true, "requires": { - "@soldoc/markdown": "^0.1.0", - "chalk": "^2.3.1", - "deep-assign": "^2.0.0", - "fs-extra": "^5.0.0", - "shelljs": "^0.8.1", - "solc": "^0.4.19", - "valid-url": "^1.0.9", - "yargs": "^11.0.0" + "@soldoc/markdown": "0.1.0", + "chalk": "2.4.1", + "deep-assign": "2.0.0", + "fs-extra": "5.0.0", + "shelljs": "0.8.2", + "solc": "0.4.24", + "valid-url": "1.0.9", + "yargs": "11.0.0" }, "dependencies": { "fs-extra": { @@ -32,9 +32,9 @@ "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" } } } @@ -50,7 +50,7 @@ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", "requires": { - "xtend": "~4.0.0" + "xtend": "4.0.1" } }, "accepts": { @@ -58,7 +58,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "~2.1.18", + "mime-types": "2.1.18", "negotiator": "0.6.1" } }, @@ -72,7 +72,7 @@ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", "requires": { - "acorn": "^4.0.3" + "acorn": "4.0.13" }, "dependencies": { "acorn": { @@ -88,7 +88,7 @@ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "^3.0.4" + "acorn": "3.3.0" }, "dependencies": { "acorn": { @@ -109,10 +109,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ajv-keywords": { @@ -126,9 +126,9 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" } }, "ambi": { @@ -137,8 +137,8 @@ "integrity": "sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA=", "dev": true, "requires": { - "editions": "^1.1.1", - "typechecker": "^4.3.0" + "editions": "1.3.4", + "typechecker": "4.5.0" }, "dependencies": { "typechecker": { @@ -147,7 +147,7 @@ "integrity": "sha512-bqPE/ck3bVIaXP7gMKTKSHrypT32lpYTpiqzPYeYzdSQnmaGvaGhy7TnN/M/+5R+2rs/kKcp9ZLPRp/Q9Yj+4w==", "dev": true, "requires": { - "editions": "^1.3.4" + "editions": "1.3.4" } } } @@ -174,7 +174,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.1" } }, "any-promise": { @@ -188,8 +188,8 @@ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" } }, "argparse": { @@ -197,7 +197,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { - "sprintf-js": "~1.0.2" + "sprintf-js": "1.0.3" } }, "arguments-extended": { @@ -206,8 +206,8 @@ "integrity": "sha1-YQfkkX0OtvCk3WYyD8Fa/HLvSUY=", "dev": true, "requires": { - "extended": "~0.0.3", - "is-extended": "~0.0.8" + "extended": "0.0.6", + "is-extended": "0.0.10" } }, "arr-diff": { @@ -216,7 +216,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "arr-flatten": "1.1.0" } }, "arr-flatten": { @@ -235,9 +235,9 @@ "integrity": "sha1-1xRK50jek8pybxIQCdv/FibRZL0=", "dev": true, "requires": { - "arguments-extended": "~0.0.3", - "extended": "~0.0.3", - "is-extended": "~0.0.3" + "arguments-extended": "0.0.3", + "extended": "0.0.6", + "is-extended": "0.0.10" } }, "array-flatten": { @@ -251,7 +251,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "^1.0.1" + "array-uniq": "1.0.3" } }, "array-uniq": { @@ -288,9 +288,9 @@ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "bn.js": "4.11.6", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" } }, "assert": { @@ -326,7 +326,7 @@ "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", "requires": { - "async": "^2.4.0" + "async": "2.6.0" }, "dependencies": { "async": { @@ -334,7 +334,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } } } @@ -369,9 +369,9 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" }, "dependencies": { "ansi-styles": { @@ -384,11 +384,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, "supports-color": { @@ -403,25 +403,25 @@ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.0", - "debug": "^2.6.8", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.7", - "slash": "^1.0.0", - "source-map": "^0.5.6" + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.1", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.5", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" } }, "babel-generator": { @@ -429,14 +429,14 @@ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.5", + "source-map": "0.5.7", + "trim-right": "1.0.1" }, "dependencies": { "jsesc": { @@ -451,9 +451,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -461,9 +461,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-call-delegate": { @@ -471,10 +471,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-define-map": { @@ -482,10 +482,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.5" } }, "babel-helper-explode-assignable-expression": { @@ -493,9 +493,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-explode-class": { @@ -503,10 +503,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", "requires": { - "babel-helper-bindify-decorators": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-bindify-decorators": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-function-name": { @@ -514,11 +514,11 @@ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-get-function-arity": { @@ -526,8 +526,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-hoist-variables": { @@ -535,8 +535,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-optimise-call-expression": { @@ -544,8 +544,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-regex": { @@ -553,9 +553,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.5" } }, "babel-helper-remap-async-to-generator": { @@ -563,11 +563,11 @@ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-replace-supers": { @@ -575,12 +575,12 @@ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helpers": { @@ -588,8 +588,8 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-messages": { @@ -597,7 +597,7 @@ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-check-es2015-constants": { @@ -605,7 +605,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-syntax-async-functions": { @@ -653,9 +653,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-generators": "^6.5.0", - "babel-runtime": "^6.22.0" + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-generators": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-async-to-generator": { @@ -663,9 +663,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-class-properties": { @@ -673,10 +673,10 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-plugin-syntax-class-properties": "6.13.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-decorators": { @@ -684,11 +684,11 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", "requires": { - "babel-helper-explode-class": "^6.24.1", - "babel-plugin-syntax-decorators": "^6.13.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-explode-class": "6.24.1", + "babel-plugin-syntax-decorators": "6.13.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -696,7 +696,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -704,7 +704,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -712,11 +712,11 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.5" } }, "babel-plugin-transform-es2015-classes": { @@ -724,15 +724,15 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -740,8 +740,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-destructuring": { @@ -749,7 +749,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -757,8 +757,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-for-of": { @@ -766,7 +766,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -774,9 +774,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-literals": { @@ -784,7 +784,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -792,9 +792,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -802,10 +802,10 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -813,9 +813,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -823,9 +823,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-object-super": { @@ -833,8 +833,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -842,12 +842,12 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -855,8 +855,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-spread": { @@ -864,7 +864,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -872,9 +872,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-template-literals": { @@ -882,7 +882,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -890,7 +890,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -898,9 +898,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" } }, "babel-plugin-transform-exponentiation-operator": { @@ -908,9 +908,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-object-rest-spread": { @@ -918,8 +918,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" + "babel-plugin-syntax-object-rest-spread": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-regenerator": { @@ -927,7 +927,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "requires": { - "regenerator-transform": "^0.10.0" + "regenerator-transform": "0.10.1" } }, "babel-plugin-transform-strict-mode": { @@ -935,8 +935,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-polyfill": { @@ -944,9 +944,9 @@ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" + "babel-runtime": "6.26.0", + "core-js": "2.5.3", + "regenerator-runtime": "0.10.5" } }, "babel-preset-env": { @@ -954,36 +954,36 @@ "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^2.1.2", - "invariant": "^2.2.2", - "semver": "^5.3.0" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "2.11.3", + "invariant": "2.2.3", + "semver": "5.5.0" } }, "babel-preset-es2015": { @@ -991,30 +991,30 @@ "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0" } }, "babel-preset-stage-2": { @@ -1022,10 +1022,10 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", "requires": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", - "babel-preset-stage-3": "^6.24.1" + "babel-plugin-syntax-dynamic-import": "6.18.0", + "babel-plugin-transform-class-properties": "6.24.1", + "babel-plugin-transform-decorators": "6.24.1", + "babel-preset-stage-3": "6.24.1" } }, "babel-preset-stage-3": { @@ -1033,11 +1033,11 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", "requires": { - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-exponentiation-operator": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.22.0" + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-generator-functions": "6.24.1", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-object-rest-spread": "6.26.0" } }, "babel-register": { @@ -1045,13 +1045,13 @@ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" + "babel-core": "6.26.0", + "babel-runtime": "6.26.0", + "core-js": "2.5.3", + "home-or-tmp": "2.0.0", + "lodash": "4.17.5", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" } }, "babel-runtime": { @@ -1059,8 +1059,8 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "core-js": "2.5.3", + "regenerator-runtime": "0.11.1" }, "dependencies": { "regenerator-runtime": { @@ -1075,11 +1075,11 @@ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.5" } }, "babel-traverse": { @@ -1087,15 +1087,15 @@ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.3", + "lodash": "4.17.5" } }, "babel-types": { @@ -1103,10 +1103,10 @@ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.5", + "to-fast-properties": "1.0.3" } }, "babelify": { @@ -1114,8 +1114,8 @@ "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" + "babel-core": "6.26.0", + "object-assign": "4.1.1" } }, "babylon": { @@ -1133,13 +1133,13 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" }, "dependencies": { "define-property": { @@ -1147,7 +1147,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -1155,7 +1155,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -1163,7 +1163,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -1171,9 +1171,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -1204,7 +1204,7 @@ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "big.js": { @@ -1232,7 +1232,7 @@ "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.1" } }, "bitcore-lib": { @@ -1241,12 +1241,12 @@ "integrity": "sha512-AeXLWhiivF6CDFzrABZHT4jJrflyylDWTi32o30rF92HW9msfuKpjzrHtFKYGa9w0kNVv5HABQjCB3OEav4PhQ==", "dev": true, "requires": { - "bn.js": "=4.11.8", - "bs58": "=4.0.1", - "buffer-compare": "=1.1.1", - "elliptic": "=6.4.0", - "inherits": "=2.0.1", - "lodash": "=4.17.4" + "bn.js": "4.11.8", + "bs58": "4.0.1", + "buffer-compare": "1.1.1", + "elliptic": "6.4.0", + "inherits": "2.0.1", + "lodash": "4.17.4" }, "dependencies": { "base-x": { @@ -1255,7 +1255,7 @@ "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.1" } }, "bn.js": { @@ -1270,7 +1270,7 @@ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dev": true, "requires": { - "base-x": "^3.0.2" + "base-x": "3.0.4" } }, "inherits": { @@ -1293,8 +1293,8 @@ "integrity": "sha512-sbeP4xwkindLMfIQhVxj6rZSDMwtiKmfc1DqvwpR6Yg+Qo4I4WHO5pvzb12Y04uDh1N3zgD45esHhfH0HHmE4g==", "dev": true, "requires": { - "bitcore-lib": "^0.15.0", - "unorm": "^1.3.3" + "bitcore-lib": "0.15.0", + "unorm": "1.4.1" } }, "bl": { @@ -1302,8 +1302,8 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "readable-stream": "2.3.5", + "safe-buffer": "5.1.1" } }, "block-stream": { @@ -1311,7 +1311,7 @@ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "requires": { - "inherits": "~2.0.0" + "inherits": "2.0.3" } }, "bluebird": { @@ -1330,15 +1330,15 @@ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", "requires": { "bytes": "3.0.0", - "content-type": "~1.0.4", + "content-type": "1.0.4", "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", + "depd": "1.1.2", + "http-errors": "1.6.2", "iconv-lite": "0.4.19", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.5.1", "raw-body": "2.3.2", - "type-is": "~1.6.15" + "type-is": "1.6.16" } }, "boom": { @@ -1346,7 +1346,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "requires": { - "hoek": "4.x.x" + "hoek": "4.2.1" } }, "borc": { @@ -1355,10 +1355,10 @@ "integrity": "sha512-2mfipKUXn7yLgwn8D5jZkJqd2ZyzqmYZQX/9d4On33oGNDLwxj5qQMst+nkKyEdaujQRFfrZCId+k8wehQVANg==", "dev": true, "requires": { - "bignumber.js": "^6.0.0", - "commander": "^2.15.0", - "ieee754": "^1.1.8", - "json-text-sequence": "^0.1" + "bignumber.js": "6.0.0", + "commander": "2.16.0", + "ieee754": "1.1.10", + "json-text-sequence": "0.1.1" }, "dependencies": { "bignumber.js": { @@ -1380,7 +1380,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -1390,9 +1390,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" } }, "brorand": { @@ -1411,12 +1411,12 @@ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "browserify-cipher": { @@ -1424,9 +1424,9 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" } }, "browserify-des": { @@ -1434,9 +1434,9 @@ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1" + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" } }, "browserify-rsa": { @@ -1444,8 +1444,8 @@ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.6", + "randombytes": "2.0.6" } }, "browserify-sha3": { @@ -1453,7 +1453,7 @@ "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", "requires": { - "js-sha3": "^0.3.1" + "js-sha3": "0.3.1" }, "dependencies": { "js-sha3": { @@ -1468,13 +1468,13 @@ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "bn.js": "4.11.6", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" } }, "browserify-zlib": { @@ -1482,7 +1482,7 @@ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "requires": { - "pako": "~1.0.5" + "pako": "1.0.6" } }, "browserslist": { @@ -1490,8 +1490,8 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", "requires": { - "caniuse-lite": "^1.0.30000792", - "electron-to-chromium": "^1.3.30" + "caniuse-lite": "1.0.30000819", + "electron-to-chromium": "1.3.40" } }, "bs58": { @@ -1499,7 +1499,7 @@ "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", "requires": { - "base-x": "^1.1.0" + "base-x": "1.1.0" } }, "bs58check": { @@ -1507,8 +1507,8 @@ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", "requires": { - "bs58": "^3.1.0", - "create-hash": "^1.1.0" + "bs58": "3.1.0", + "create-hash": "1.1.3" } }, "bson": { @@ -1523,8 +1523,8 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "1.2.3", + "ieee754": "1.1.10" } }, "buffer-compare": { @@ -1574,15 +1574,15 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" }, "dependencies": { "isobject": { @@ -1598,7 +1598,7 @@ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "^0.2.0" + "callsites": "0.2.0" } }, "callsites": { @@ -1618,8 +1618,8 @@ "integrity": "sha1-7B7ARXZkoPCSZDt8ZGxFfVzW9pM=", "dev": true, "requires": { - "bluebird": "^3.4.6", - "uuid": "^3.0.1" + "bluebird": "3.5.1", + "uuid": "3.2.1" } }, "caniuse-lite": { @@ -1637,8 +1637,8 @@ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "align-text": "0.1.4", + "lazy-cache": "1.0.4" } }, "chalk": { @@ -1646,9 +1646,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" } }, "chardet": { @@ -1662,7 +1662,7 @@ "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", "requires": { - "functional-red-black-tree": "^1.0.1" + "functional-red-black-tree": "1.0.1" } }, "chokidar": { @@ -1671,15 +1671,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.1.3", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" } }, "cipher-base": { @@ -1687,8 +1687,8 @@ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "circular-json": { @@ -1702,10 +1702,10 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" }, "dependencies": { "define-property": { @@ -1713,7 +1713,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "isobject": { @@ -1729,12 +1729,12 @@ "integrity": "sha1-OlrnT9drYmevZm5p4q+70B3vNNE=", "dev": true, "requires": { - "ansi-regex": "^2.1.1", - "d": "1", - "es5-ext": "^0.10.12", - "es6-iterator": "2", - "memoizee": "^0.4.3", - "timers-ext": "0.1" + "ansi-regex": "2.1.1", + "d": "1.0.0", + "es5-ext": "0.10.39", + "es6-iterator": "2.0.3", + "memoizee": "0.4.12", + "timers-ext": "0.1.3" } }, "cli-cursor": { @@ -1743,7 +1743,7 @@ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "restore-cursor": "2.0.0" } }, "cli-width": { @@ -1758,9 +1758,9 @@ "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" }, "dependencies": { "ansi-regex": { @@ -1775,7 +1775,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "3.0.0" } } } @@ -1795,8 +1795,8 @@ "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", "requires": { - "bs58": "^2.0.1", - "create-hash": "^1.1.1" + "bs58": "2.0.1", + "create-hash": "1.1.3" }, "dependencies": { "bs58": { @@ -1811,8 +1811,8 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "map-visit": "1.0.0", + "object-visit": "1.0.1" } }, "color-convert": { @@ -1820,7 +1820,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "requires": { - "color-name": "^1.1.1" + "color-name": "1.1.3" } }, "color-name": { @@ -1839,7 +1839,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "commander": { @@ -1869,10 +1869,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "buffer-from": "1.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" } }, "console-browserify": { @@ -1880,7 +1880,7 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "requires": { - "date-now": "^0.1.4" + "date-now": "0.1.4" } }, "constants-browserify": { @@ -1939,8 +1939,8 @@ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", "requires": { - "object-assign": "^4", - "vary": "^1" + "object-assign": "4.1.1", + "vary": "1.1.2" } }, "coveralls": { @@ -1948,11 +1948,11 @@ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", "requires": { - "js-yaml": "^3.6.1", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.5", - "minimist": "^1.2.0", - "request": "^2.79.0" + "js-yaml": "3.11.0", + "lcov-parse": "0.0.10", + "log-driver": "1.2.7", + "minimist": "1.2.0", + "request": "2.85.0" }, "dependencies": { "minimist": { @@ -1967,8 +1967,8 @@ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "bn.js": "4.11.6", + "elliptic": "6.4.0" } }, "create-hash": { @@ -1976,10 +1976,10 @@ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "sha.js": "^2.4.0" + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.10" } }, "create-hmac": { @@ -1987,12 +1987,12 @@ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.10" } }, "cron-parser": { @@ -2001,8 +2001,8 @@ "integrity": "sha512-gzmXu16/prizIbKPPKJo+WgBpV7k8Rxxu9FgaANW+vx5DebCXavfRqbROjKkr9ETvVPqs+IO+NXj4GG/eLf8zQ==", "dev": true, "requires": { - "is-nan": "^1.2.1", - "moment-timezone": "^0.5.0" + "is-nan": "1.2.1", + "moment-timezone": "0.5.21" } }, "cryptiles": { @@ -2010,7 +2010,7 @@ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "requires": { - "boom": "5.x.x" + "boom": "5.2.0" }, "dependencies": { "boom": { @@ -2018,7 +2018,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "requires": { - "hoek": "4.x.x" + "hoek": "4.2.1" } } } @@ -2028,17 +2028,17 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.6", + "randomfill": "1.0.4" } }, "crypto-js": { @@ -2069,7 +2069,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "^0.10.9" + "es5-ext": "0.10.39" } }, "dashdash": { @@ -2077,7 +2077,7 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "date-extended": { @@ -2086,9 +2086,9 @@ "integrity": "sha1-I4AtV90b94GIE/4MMuhRqG2iZ8k=", "dev": true, "requires": { - "array-extended": "~0.0.3", - "extended": "~0.0.3", - "is-extended": "~0.0.3" + "array-extended": "0.0.11", + "extended": "0.0.6", + "is-extended": "0.0.10" } }, "date-now": { @@ -2131,14 +2131,14 @@ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" + "decompress-tar": "4.1.1", + "decompress-tarbz2": "4.1.1", + "decompress-targz": "4.1.1", + "decompress-unzip": "4.0.1", + "graceful-fs": "4.1.11", + "make-dir": "1.2.0", + "pify": "2.3.0", + "strip-dirs": "2.1.0" }, "dependencies": { "pify": { @@ -2153,7 +2153,7 @@ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "requires": { - "mimic-response": "^1.0.0" + "mimic-response": "1.0.0" } }, "decompress-tar": { @@ -2161,9 +2161,9 @@ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" + "file-type": "5.2.0", + "is-stream": "1.1.0", + "tar-stream": "1.5.5" } }, "decompress-tarbz2": { @@ -2171,11 +2171,11 @@ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" + "decompress-tar": "4.1.1", + "file-type": "6.2.0", + "is-stream": "1.1.0", + "seek-bzip": "1.0.5", + "unbzip2-stream": "1.2.5" }, "dependencies": { "file-type": { @@ -2190,9 +2190,9 @@ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" + "decompress-tar": "4.1.1", + "file-type": "5.2.0", + "is-stream": "1.1.0" } }, "decompress-unzip": { @@ -2200,10 +2200,10 @@ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" + "file-type": "3.9.0", + "get-stream": "2.3.1", + "pify": "2.3.0", + "yauzl": "2.9.1" }, "dependencies": { "file-type": { @@ -2216,8 +2216,8 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" + "object-assign": "4.1.1", + "pinkie-promise": "2.0.1" } }, "pify": { @@ -2233,7 +2233,7 @@ "integrity": "sha1-6+BrHwfwja5ZdiDj3RYi83GhxXI=", "dev": true, "requires": { - "is-obj": "^1.0.0" + "is-obj": "1.0.1" } }, "deep-equal": { @@ -2252,7 +2252,7 @@ "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", "requires": { - "abstract-leveldown": "~2.6.0" + "abstract-leveldown": "2.6.3" } }, "define-properties": { @@ -2260,8 +2260,8 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" + "foreach": "2.0.5", + "object-keys": "1.0.11" }, "dependencies": { "object-keys": { @@ -2276,8 +2276,8 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "is-descriptor": "1.0.2", + "isobject": "3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -2285,7 +2285,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -2293,7 +2293,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -2301,9 +2301,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -2329,13 +2329,13 @@ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.2.8" }, "dependencies": { "globby": { @@ -2344,12 +2344,12 @@ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "pify": { @@ -2381,8 +2381,8 @@ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" } }, "destroy": { @@ -2395,7 +2395,7 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "diff": { @@ -2409,9 +2409,9 @@ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "bn.js": "4.11.6", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" } }, "doctrine": { @@ -2420,7 +2420,7 @@ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "^2.0.2" + "esutils": "2.0.2" } }, "dom-walk": { @@ -2438,9 +2438,9 @@ "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6" } }, "duplexer3": { @@ -2454,7 +2454,7 @@ "integrity": "sha1-Rm98qhBwj2EFCeMsgHqv5X/BIr8=", "dev": true, "requires": { - "typechecker": "^2.0.8" + "typechecker": "2.1.0" } }, "ecc-jsbn": { @@ -2463,7 +2463,7 @@ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "editions": { @@ -2487,13 +2487,13 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "bn.js": "4.11.6", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" } }, "emojis-list": { @@ -2511,7 +2511,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "~0.4.13" + "iconv-lite": "0.4.19" } }, "end-of-stream": { @@ -2519,7 +2519,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { - "once": "^1.4.0" + "once": "1.4.0" } }, "errno": { @@ -2527,7 +2527,7 @@ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "requires": { - "prr": "~1.0.1" + "prr": "1.0.1" } }, "error-ex": { @@ -2535,7 +2535,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "requires": { - "is-arrayish": "^0.2.1" + "is-arrayish": "0.2.1" } }, "es-abstract": { @@ -2543,11 +2543,11 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" } }, "es-to-primitive": { @@ -2555,9 +2555,9 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" } }, "es5-ext": { @@ -2565,8 +2565,8 @@ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.39.tgz", "integrity": "sha512-AlaXZhPHl0po/uxMx1tyrlt1O86M6D5iVaDH8UgLfgek4kXTX6vzsRfJQWC2Ku+aG8pkw1XWzh9eTkwfVrsD5g==", "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1" + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" } }, "es6-iterator": { @@ -2574,9 +2574,9 @@ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "d": "1.0.0", + "es5-ext": "0.10.39", + "es6-symbol": "3.1.1" } }, "es6-map": { @@ -2584,12 +2584,12 @@ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" + "d": "1.0.0", + "es5-ext": "0.10.39", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" } }, "es6-set": { @@ -2597,11 +2597,11 @@ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", + "d": "1.0.0", + "es5-ext": "0.10.39", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" + "event-emitter": "0.3.5" } }, "es6-symbol": { @@ -2609,8 +2609,8 @@ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "1.0.0", + "es5-ext": "0.10.39" } }, "es6-weak-map": { @@ -2618,10 +2618,10 @@ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" + "d": "1.0.0", + "es5-ext": "0.10.39", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" } }, "escape-html": { @@ -2640,11 +2640,11 @@ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" }, "dependencies": { "esprima": { @@ -2666,7 +2666,7 @@ "dev": true, "optional": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -2676,10 +2676,10 @@ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.1", + "estraverse": "4.2.0" } }, "eslint": { @@ -2688,44 +2688,44 @@ "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", + "ajv": "5.5.2", + "babel-code-frame": "6.26.0", + "chalk": "2.3.2", + "concat-stream": "1.6.2", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.1.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "1.0.0", + "espree": "3.5.4", + "esquery": "1.0.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "11.4.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.1.0", + "js-yaml": "3.11.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.5", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "regexpp": "1.1.0", + "require-uncached": "1.0.3", + "semver": "5.5.0", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", "table": "4.0.2", - "text-table": "~0.2.0" + "text-table": "0.2.0" }, "dependencies": { "ansi-regex": { @@ -2740,7 +2740,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.1" } }, "chalk": { @@ -2749,9 +2749,9 @@ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.0" } }, "cross-spawn": { @@ -2760,9 +2760,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "lru-cache": "4.1.2", + "shebang-command": "1.2.0", + "which": "1.3.0" } }, "debug": { @@ -2786,20 +2786,20 @@ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", + "ansi-escapes": "3.0.0", + "chalk": "2.3.2", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.1.0", + "figures": "2.0.0", + "lodash": "4.17.5", "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" } }, "strip-ansi": { @@ -2808,7 +2808,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "3.0.0" } }, "supports-color": { @@ -2817,7 +2817,7 @@ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -2834,8 +2834,8 @@ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", "dev": true, "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" + "debug": "2.6.9", + "resolve": "1.5.0" } }, "eslint-module-utils": { @@ -2844,8 +2844,8 @@ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", "dev": true, "requires": { - "debug": "^2.6.8", - "pkg-dir": "^1.0.0" + "debug": "2.6.9", + "pkg-dir": "1.0.0" } }, "eslint-plugin-import": { @@ -2854,16 +2854,16 @@ "integrity": "sha1-+gkIPVp1KI35xsfQn+EiVZhWVec=", "dev": true, "requires": { - "builtin-modules": "^1.1.1", - "contains-path": "^0.1.0", - "debug": "^2.6.8", + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.6.9", "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0" + "eslint-import-resolver-node": "0.3.2", + "eslint-module-utils": "2.2.0", + "has": "1.0.1", + "lodash": "4.17.5", + "minimatch": "3.0.4", + "read-pkg-up": "2.0.0" }, "dependencies": { "doctrine": { @@ -2872,8 +2872,8 @@ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "esutils": "2.0.2", + "isarray": "1.0.0" } }, "load-json-file": { @@ -2882,10 +2882,10 @@ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" } }, "parse-json": { @@ -2894,7 +2894,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "path-type": { @@ -2903,7 +2903,7 @@ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { - "pify": "^2.0.0" + "pify": "2.3.0" } }, "pify": { @@ -2918,9 +2918,9 @@ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" } }, "read-pkg-up": { @@ -2929,8 +2929,8 @@ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "find-up": "2.1.0", + "read-pkg": "2.0.0" } }, "strip-bom": { @@ -2947,10 +2947,10 @@ "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", "dev": true, "requires": { - "ignore": "^3.3.6", - "minimatch": "^3.0.4", - "resolve": "^1.3.3", - "semver": "^5.4.1" + "ignore": "3.3.7", + "minimatch": "3.0.4", + "resolve": "1.5.0", + "semver": "5.5.0" } }, "eslint-plugin-promise": { @@ -2971,8 +2971,8 @@ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "esrecurse": "4.2.1", + "estraverse": "4.2.0" } }, "eslint-visitor-keys": { @@ -2987,8 +2987,8 @@ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "acorn": "5.5.3", + "acorn-jsx": "3.0.1" } }, "esprima": { @@ -3002,7 +3002,7 @@ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "4.2.0" } }, "esrecurse": { @@ -3010,7 +3010,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "requires": { - "estraverse": "^4.1.0" + "estraverse": "4.2.0" } }, "estraverse": { @@ -3034,13 +3034,13 @@ "integrity": "sha512-yrNyBIBKC7WfUjrXSG/CZVy0gW2aF8+MnjnrkOxkZOR+BAtL6JgYOnzVnrU8KE6mKJETlA/1dYMygvLXWyJGGw==", "requires": { "async-eventemitter": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" + "eth-query": "2.1.2", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.1.5", + "ethjs-util": "0.1.4", + "json-rpc-engine": "3.6.1", + "pify": "2.3.0", + "tape": "4.9.0" }, "dependencies": { "async": { @@ -3048,14 +3048,13 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } }, "async-eventemitter": { "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "from": "async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", "requires": { - "async": "^2.4.0" + "async": "2.6.0" } }, "ethereumjs-util": { @@ -3063,13 +3062,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } }, "pify": { @@ -3084,13 +3083,13 @@ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "keccakjs": "^0.2.1", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" + "bn.js": "4.11.6", + "elliptic": "6.4.0", + "keccakjs": "0.2.1", + "nano-json-stream-parser": "0.1.2", + "servify": "0.1.12", + "ws": "3.3.3", + "xhr-request-promise": "0.1.2" } }, "eth-lightwallet": { @@ -3099,22 +3098,21 @@ "integrity": "sha512-79vVCETy+4l1b6wuOWwjqPW3Bom5ZK46BgkUNwaXhiMG1rrMRHjpjYEWMqH0JHeCzOzB4HBIFz7eK1/4s6w5nA==", "dev": true, "requires": { - "bitcore-lib": "^0.15.0", - "bitcore-mnemonic": "^1.5.0", - "buffer": "^4.9.0", - "crypto-js": "^3.1.5", - "elliptic": "^3.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.1", - "rlp": "^2.0.0", - "scrypt-async": "^1.2.0", + "bitcore-lib": "0.15.0", + "bitcore-mnemonic": "1.5.0", + "buffer": "4.9.1", + "crypto-js": "3.1.8", + "elliptic": "3.1.0", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.2.0", + "rlp": "2.0.0", + "scrypt-async": "1.3.1", "tweetnacl": "0.13.2", "web3": "0.20.2" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "dev": true }, "bn.js": { @@ -3129,9 +3127,9 @@ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "base64-js": "1.2.3", + "ieee754": "1.1.10", + "isarray": "1.0.0" } }, "elliptic": { @@ -3140,10 +3138,10 @@ "integrity": "sha1-whaC73YnabVqdCAWCRBdoR1fYMw=", "dev": true, "requires": { - "bn.js": "^2.0.3", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" + "bn.js": "2.2.0", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "inherits": "2.0.3" } }, "ethereumjs-util": { @@ -3152,13 +3150,13 @@ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.8", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" }, "dependencies": { "bn.js": { @@ -3182,10 +3180,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" + "crypto-js": "3.1.8", + "utf8": "2.1.1", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" } } } @@ -3195,8 +3193,8 @@ "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", "requires": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" + "json-rpc-random-id": "1.0.1", + "xtend": "4.0.1" } }, "eth-sig-util": { @@ -3205,15 +3203,14 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "ethereumjs-util": "^5.1.1" + "ethereumjs-util": "5.1.5" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" + "bn.js": "4.11.6", + "ethereumjs-util": "5.1.5" } }, "ethereumjs-util": { @@ -3221,13 +3218,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } } } @@ -3238,31 +3235,31 @@ "integrity": "sha512-yDTivI85618BoLI71yNRzW6iVcVN2rjnviCIzs0QOCOENj4XpYQhMDGhdqDi8XWDdzTd0Ja/Canuuh3vfE2IcA==", "dev": true, "requires": { - "async": "^2.4.1", - "borc": "^2.0.2", + "async": "2.6.1", + "borc": "2.0.3", "caminte": "0.3.7", - "colors": "^1.1.2", - "compare-versions": "^3.0.1", - "crypto-random-string": "^1.0.0", - "eth-lightwallet": "^3.0.1", + "colors": "1.2.1", + "compare-versions": "3.3.0", + "crypto-random-string": "1.0.0", + "eth-lightwallet": "3.0.1", "ethereumjs-abi": "0.6.4", - "ethereumjs-tx": "^1.3.1", - "ethereumjs-util": "^5.2.0", - "i18n": "^0.8.3", - "moment": "^2.22.2", - "multihashes": "^0.4.5", - "node-async-loop": "^1.2.2", - "node-cache": "^4.1.1", - "node-schedule": "^1.2.3", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.2.0", + "i18n": "0.8.3", + "moment": "2.22.2", + "multihashes": "0.4.13", + "node-async-loop": "1.2.2", + "node-cache": "4.2.0", + "node-schedule": "1.3.0", "pragma-singleton": "1.0.3", - "request": "^2.81.0", - "semver": "^5.5.0", - "stdio": "^0.2.7", - "tingodb": "^0.6.1", - "underscore": "^1.8.3", - "utf8": "^2.1.2", + "request": "2.85.0", + "semver": "5.5.0", + "stdio": "0.2.7", + "tingodb": "0.6.1", + "underscore": "1.9.1", + "utf8": "2.1.2", "web3": "0.19.1", - "winston": "^2.3.1" + "winston": "2.4.3" }, "dependencies": { "async": { @@ -3271,7 +3268,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } }, "bignumber.js": { @@ -3286,8 +3283,8 @@ "integrity": "sha1-m6G7BWSS0AwnJ59uzNTVgnWRLBo=", "dev": true, "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" + "bn.js": "4.11.6", + "ethereumjs-util": "4.5.0" }, "dependencies": { "ethereumjs-util": { @@ -3296,11 +3293,11 @@ "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "dev": true, "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "keccakjs": "0.2.1", + "rlp": "2.0.0", + "secp256k1": "3.5.0" } } } @@ -3311,13 +3308,13 @@ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } }, "lodash": { @@ -3344,11 +3341,11 @@ "integrity": "sha1-52PVsRB8S8JKvU+MvuG6Nlnm6zE=", "dev": true, "requires": { - "bignumber.js": "^4.0.2", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" + "bignumber.js": "4.1.0", + "crypto-js": "3.1.8", + "utf8": "2.1.2", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" } } } @@ -3364,8 +3361,8 @@ "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", "dev": true, "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" + "bn.js": "4.11.6", + "ethereumjs-util": "4.5.0" } }, "ethereumjs-account": { @@ -3373,8 +3370,8 @@ "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.4.tgz", "integrity": "sha1-+MMCMby3B/RRTYoFLB+doQNiTUc=", "requires": { - "ethereumjs-util": "^4.0.1", - "rlp": "^2.0.0" + "ethereumjs-util": "4.5.0", + "rlp": "2.0.0" } }, "ethereumjs-block": { @@ -3382,11 +3379,11 @@ "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", "requires": { - "async": "^2.0.1", + "async": "2.6.0", "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.1.5", + "merkle-patricia-tree": "2.3.1" }, "dependencies": { "async": { @@ -3394,7 +3391,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } }, "ethereumjs-util": { @@ -3402,13 +3399,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } } } @@ -3418,7 +3415,7 @@ "resolved": "https://registry.npmjs.org/ethereumjs-testrpc/-/ethereumjs-testrpc-6.0.3.tgz", "integrity": "sha512-lAxxsxDKK69Wuwqym2K49VpXtBvLEsXr1sryNG4AkvL5DomMdeCBbu3D87UEevKenLHBiT8GTjARwN6Yj039gA==", "requires": { - "webpack": "^3.0.0" + "webpack": "3.11.0" } }, "ethereumjs-testrpc-sc": { @@ -3427,7 +3424,7 @@ "integrity": "sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg==", "dev": true, "requires": { - "source-map-support": "^0.5.3" + "source-map-support": "0.5.9" }, "dependencies": { "source-map": { @@ -3442,8 +3439,8 @@ "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "buffer-from": "1.0.0", + "source-map": "0.6.1" } } } @@ -3453,8 +3450,8 @@ "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz", "integrity": "sha512-kOgUd5jC+0tgV7t52UDECMMz9Uf+Lro+6fSpCvzWemtXfMEcwI3EOxf5mVPMRbTFkMMhuERokNNVF3jItAjidg==", "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" + "ethereum-common": "0.0.18", + "ethereumjs-util": "5.1.5" }, "dependencies": { "ethereum-common": { @@ -3467,13 +3464,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } } } @@ -3483,11 +3480,11 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "keccakjs": "0.2.1", + "rlp": "2.0.0", + "secp256k1": "3.5.0" } }, "ethereumjs-vm": { @@ -3495,17 +3492,17 @@ "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.3.tgz", "integrity": "sha512-yIWJqTEcrF9vJTCvNMxacRkAx6zIZTOW0SmSA+hSFiU1x8JyVZDi9o5udwsRVECT5RkPgQzm62kpL6Pf4qemsw==", "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", + "async": "2.6.0", + "async-eventemitter": "0.2.4", "ethereum-common": "0.2.0", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~1.7.0", - "ethereumjs-util": "^5.1.3", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.1.1", - "safe-buffer": "^5.1.1" + "ethereumjs-account": "2.0.4", + "ethereumjs-block": "1.7.1", + "ethereumjs-util": "5.1.5", + "fake-merkle-patricia-tree": "1.0.1", + "functional-red-black-tree": "1.0.1", + "merkle-patricia-tree": "2.3.1", + "rustbn.js": "0.1.2", + "safe-buffer": "5.1.1" }, "dependencies": { "async": { @@ -3513,7 +3510,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } }, "ethereumjs-util": { @@ -3521,13 +3518,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } } } @@ -3537,13 +3534,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", "requires": { - "aes-js": "^0.2.3", - "bs58check": "^1.0.8", - "ethereumjs-util": "^4.4.0", - "hdkey": "^0.7.0", - "scrypt.js": "^0.2.0", - "utf8": "^2.1.1", - "uuid": "^2.0.1" + "aes-js": "0.2.4", + "bs58check": "1.3.4", + "ethereumjs-util": "4.5.0", + "hdkey": "0.7.1", + "scrypt.js": "0.2.0", + "utf8": "2.1.1", + "uuid": "2.0.3" }, "dependencies": { "uuid": { @@ -3559,9 +3556,9 @@ "integrity": "sha512-d/tiMUavaeaY2GFqjpgfPzT46cEc0cilP3hnlTXR3LR/HR5Qrhv4PfdgW3gxBlR5aBTtUeM/lo8z8ph3JdtFhQ==", "requires": { "aes-js": "3.0.0", - "bn.js": "^4.4.0", + "bn.js": "4.11.6", "elliptic": "6.3.3", - "hash.js": "^1.0.0", + "hash.js": "1.1.3", "inherits": "2.0.1", "js-sha3": "0.5.7", "scrypt-js": "2.0.3", @@ -3580,10 +3577,10 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" + "bn.js": "4.11.6", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "inherits": "2.0.1" } }, "inherits": { @@ -3631,8 +3628,8 @@ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "1.0.0", + "es5-ext": "0.10.39" } }, "eventemitter3": { @@ -3650,8 +3647,8 @@ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" } }, "execa": { @@ -3659,13 +3656,13 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" }, "dependencies": { "cross-spawn": { @@ -3673,9 +3670,9 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "lru-cache": "4.1.2", + "shebang-command": "1.2.0", + "which": "1.3.0" } } } @@ -3686,7 +3683,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "is-posix-bracket": "0.1.1" } }, "expand-range": { @@ -3695,7 +3692,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "^2.1.0" + "fill-range": "2.2.3" } }, "express": { @@ -3703,36 +3700,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "requires": { - "accepts": "~1.3.5", + "accepts": "1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.2", "content-disposition": "0.5.2", - "content-type": "~1.0.4", + "content-type": "1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.3", + "proxy-addr": "2.0.3", "qs": "6.5.1", - "range-parser": "~1.2.0", + "range-parser": "1.2.0", "safe-buffer": "5.1.1", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", + "statuses": "1.4.0", + "type-is": "1.6.16", "utils-merge": "1.0.1", - "vary": "~1.1.2" + "vary": "1.1.2" }, "dependencies": { "setprototypeof": { @@ -3752,8 +3749,8 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -3761,7 +3758,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -3772,7 +3769,7 @@ "integrity": "sha1-f7i/e52uOXWG5IVwrP1kLHjlBmk=", "dev": true, "requires": { - "extender": "~0.0.5" + "extender": "0.0.10" } }, "extender": { @@ -3781,7 +3778,7 @@ "integrity": "sha1-WJwHSCvmGhRgttgfnCSqZ+jzJM0=", "dev": true, "requires": { - "declare.js": "~0.0.4" + "declare.js": "0.0.8" } }, "extendr": { @@ -3790,7 +3787,7 @@ "integrity": "sha1-MBqgu+pWX00tyPVw8qImEahSe1Y=", "dev": true, "requires": { - "typechecker": "~2.0.1" + "typechecker": "2.0.8" }, "dependencies": { "typechecker": { @@ -3807,9 +3804,9 @@ "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", "dev": true, "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" } }, "extglob": { @@ -3818,7 +3815,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "extract-opts": { @@ -3827,7 +3824,7 @@ "integrity": "sha1-H6KOunNSxttID4hc63GkaBC+bX0=", "dev": true, "requires": { - "typechecker": "~2.0.1" + "typechecker": "2.0.8" }, "dependencies": { "typechecker": { @@ -3854,7 +3851,7 @@ "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", "requires": { - "checkpoint-store": "^1.1.0" + "checkpoint-store": "1.1.0" } }, "fast-csv": { @@ -3891,13 +3888,13 @@ "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", "dev": true, "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.18" }, "dependencies": { "core-js": { @@ -3913,7 +3910,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "requires": { - "pend": "~1.2.0" + "pend": "1.2.0" } }, "fetch-ponyfill": { @@ -3921,7 +3918,7 @@ "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", "requires": { - "node-fetch": "~1.7.1" + "node-fetch": "1.7.3" } }, "figures": { @@ -3930,7 +3927,7 @@ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "escape-string-regexp": "1.0.5" } }, "file-entry-cache": { @@ -3939,8 +3936,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "1.3.0", + "object-assign": "4.1.1" } }, "file-type": { @@ -3960,11 +3957,11 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^1.1.3", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" } }, "finalhandler": { @@ -3973,12 +3970,12 @@ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.4.0", + "unpipe": "1.0.0" } }, "find-up": { @@ -3986,7 +3983,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "^2.0.0" + "locate-path": "2.0.0" } }, "flat-cache": { @@ -3995,10 +3992,10 @@ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" } }, "for-each": { @@ -4006,7 +4003,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", "requires": { - "is-function": "~1.0.0" + "is-function": "1.0.1" } }, "for-in": { @@ -4020,7 +4017,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "^1.0.1" + "for-in": "1.0.2" } }, "foreach": { @@ -4038,9 +4035,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "asynckit": "^0.4.0", + "asynckit": "0.4.0", "combined-stream": "1.0.6", - "mime-types": "^2.1.12" + "mime-types": "2.1.18" } }, "forwarded": { @@ -4053,7 +4050,7 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "requires": { - "map-cache": "^0.2.2" + "map-cache": "0.2.2" } }, "fresh": { @@ -4067,9 +4064,9 @@ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" } }, "fs-promise": { @@ -4077,10 +4074,10 @@ "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", "requires": { - "any-promise": "^1.3.0", - "fs-extra": "^2.0.0", - "mz": "^2.6.0", - "thenify-all": "^1.6.0" + "any-promise": "1.3.0", + "fs-extra": "2.1.2", + "mz": "2.7.0", + "thenify-all": "1.6.0" }, "dependencies": { "fs-extra": { @@ -4088,8 +4085,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0" } }, "jsonfile": { @@ -4097,7 +4094,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } } } @@ -4113,8 +4110,8 @@ "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", "optional": true, "requires": { - "nan": "^2.3.0", - "node-pre-gyp": "^0.6.39" + "nan": "2.9.2", + "node-pre-gyp": "0.6.39" }, "dependencies": { "abbrev": { @@ -4127,8 +4124,8 @@ "bundled": true, "optional": true, "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" + "co": "4.6.0", + "json-stable-stringify": "1.0.1" } }, "ansi-regex": { @@ -4145,8 +4142,8 @@ "bundled": true, "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "delegates": "1.0.0", + "readable-stream": "2.2.9" } }, "asn1": { @@ -4183,28 +4180,28 @@ "bundled": true, "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "block-stream": { "version": "0.0.9", "bundled": true, "requires": { - "inherits": "~2.0.0" + "inherits": "2.0.3" } }, "boom": { "version": "2.10.1", "bundled": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "brace-expansion": { "version": "1.1.7", "bundled": true, "requires": { - "balanced-match": "^0.4.1", + "balanced-match": "0.4.2", "concat-map": "0.0.1" } }, @@ -4230,7 +4227,7 @@ "version": "1.0.5", "bundled": true, "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "concat-map": { @@ -4249,7 +4246,7 @@ "version": "2.0.5", "bundled": true, "requires": { - "boom": "2.x.x" + "boom": "2.10.1" } }, "dashdash": { @@ -4257,7 +4254,7 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" }, "dependencies": { "assert-plus": { @@ -4299,7 +4296,7 @@ "bundled": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "extend": { @@ -4321,9 +4318,9 @@ "bundled": true, "optional": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" } }, "fs.realpath": { @@ -4334,10 +4331,10 @@ "version": "1.0.11", "bundled": true, "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" } }, "fstream-ignore": { @@ -4345,9 +4342,9 @@ "bundled": true, "optional": true, "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" } }, "gauge": { @@ -4355,14 +4352,14 @@ "bundled": true, "optional": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" } }, "getpass": { @@ -4370,7 +4367,7 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" }, "dependencies": { "assert-plus": { @@ -4384,12 +4381,12 @@ "version": "7.1.2", "bundled": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "graceful-fs": { @@ -4406,8 +4403,8 @@ "bundled": true, "optional": true, "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" + "ajv": "4.11.8", + "har-schema": "1.0.5" } }, "has-unicode": { @@ -4419,10 +4416,10 @@ "version": "3.1.3", "bundled": true, "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" } }, "hoek": { @@ -4434,17 +4431,17 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" } }, "inflight": { "version": "1.0.6", "bundled": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -4460,7 +4457,7 @@ "version": "1.0.0", "bundled": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-typedarray": { @@ -4482,7 +4479,7 @@ "bundled": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "jsbn": { @@ -4500,7 +4497,7 @@ "bundled": true, "optional": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json-stringify-safe": { @@ -4539,14 +4536,14 @@ "version": "2.1.15", "bundled": true, "requires": { - "mime-db": "~1.27.0" + "mime-db": "1.27.0" } }, "minimatch": { "version": "3.0.4", "bundled": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.7" } }, "minimist": { @@ -4570,17 +4567,17 @@ "bundled": true, "optional": true, "requires": { - "detect-libc": "^1.0.2", + "detect-libc": "1.0.2", "hawk": "3.1.3", - "mkdirp": "^0.5.1", - "nopt": "^4.0.1", - "npmlog": "^4.0.2", - "rc": "^1.1.7", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", "request": "2.81.0", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^2.2.1", - "tar-pack": "^3.4.0" + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" } }, "nopt": { @@ -4588,8 +4585,8 @@ "bundled": true, "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1.1.0", + "osenv": "0.1.4" } }, "npmlog": { @@ -4597,10 +4594,10 @@ "bundled": true, "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" } }, "number-is-nan": { @@ -4621,7 +4618,7 @@ "version": "1.4.0", "bundled": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "os-homedir": { @@ -4639,8 +4636,8 @@ "bundled": true, "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "path-is-absolute": { @@ -4671,10 +4668,10 @@ "bundled": true, "optional": true, "requires": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" }, "dependencies": { "minimist": { @@ -4688,13 +4685,13 @@ "version": "2.2.9", "bundled": true, "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" } }, "request": { @@ -4702,35 +4699,35 @@ "bundled": true, "optional": true, "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" } }, "rimraf": { "version": "2.6.1", "bundled": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "safe-buffer": { @@ -4756,7 +4753,7 @@ "version": "1.0.9", "bundled": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "sshpk": { @@ -4764,15 +4761,15 @@ "bundled": true, "optional": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jodid25519": "^1.0.0", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" }, "dependencies": { "assert-plus": { @@ -4786,16 +4783,16 @@ "version": "1.0.2", "bundled": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "string_decoder": { "version": "1.0.1", "bundled": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.0.1" } }, "stringstream": { @@ -4807,7 +4804,7 @@ "version": "3.0.1", "bundled": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-json-comments": { @@ -4819,9 +4816,9 @@ "version": "2.2.1", "bundled": true, "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" } }, "tar-pack": { @@ -4829,14 +4826,14 @@ "bundled": true, "optional": true, "requires": { - "debug": "^2.2.0", - "fstream": "^1.0.10", - "fstream-ignore": "^1.0.5", - "once": "^1.3.3", - "readable-stream": "^2.1.4", - "rimraf": "^2.5.1", - "tar": "^2.2.1", - "uid-number": "^0.0.6" + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" } }, "tough-cookie": { @@ -4844,7 +4841,7 @@ "bundled": true, "optional": true, "requires": { - "punycode": "^1.4.1" + "punycode": "1.4.1" } }, "tunnel-agent": { @@ -4852,7 +4849,7 @@ "bundled": true, "optional": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.0.1" } }, "tweetnacl": { @@ -4887,7 +4884,7 @@ "bundled": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "1.0.2" } }, "wrappy": { @@ -4901,10 +4898,10 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.2.8" } }, "function-bind": { @@ -4923,7 +4920,7 @@ "integrity": "sha512-yXzteu4SIgUL31mnpm9j+x6dpHUw0p/nsRVkcySKq0w+1vDxH9jMErP1QhZAJuTVE6ni4nfvGSNkaQx5cD3jfg==", "dev": true, "requires": { - "source-map-support": "^0.5.3" + "source-map-support": "0.5.9" }, "dependencies": { "source-map": { @@ -4938,8 +4935,8 @@ "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "buffer-from": "1.0.0", + "source-map": "0.6.1" } } } @@ -4964,7 +4961,7 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "glob": { @@ -4972,12 +4969,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-base": { @@ -4986,8 +4983,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "glob-parent": "2.0.0", + "is-glob": "2.0.1" } }, "glob-parent": { @@ -4996,7 +4993,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "2.0.1" } }, "global": { @@ -5004,8 +5001,8 @@ "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" + "min-document": "2.19.0", + "process": "0.5.2" } }, "globals": { @@ -5029,10 +5026,10 @@ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" }, "dependencies": { "source-map": { @@ -5041,7 +5038,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -5056,8 +5053,8 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, "has": { @@ -5065,7 +5062,7 @@ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "requires": { - "function-bind": "^1.0.2" + "function-bind": "1.1.1" } }, "has-ansi": { @@ -5073,7 +5070,7 @@ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "has-flag": { @@ -5091,7 +5088,7 @@ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", "requires": { - "has-symbol-support-x": "^1.4.1" + "has-symbol-support-x": "1.4.2" } }, "has-value": { @@ -5099,9 +5096,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -5116,8 +5113,8 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { "is-number": { @@ -5125,7 +5122,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5133,7 +5130,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5143,7 +5140,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5153,7 +5150,7 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", "requires": { - "inherits": "^2.0.1" + "inherits": "2.0.3" } }, "hash.js": { @@ -5161,8 +5158,8 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" } }, "hawk": { @@ -5170,10 +5167,10 @@ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "requires": { - "boom": "4.x.x", - "cryptiles": "3.x.x", - "hoek": "4.x.x", - "sntp": "2.x.x" + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.1", + "sntp": "2.1.0" } }, "hdkey": { @@ -5181,8 +5178,8 @@ "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", "requires": { - "coinstring": "^2.0.0", - "secp256k1": "^3.0.1" + "coinstring": "2.3.0", + "secp256k1": "3.5.0" } }, "he": { @@ -5196,9 +5193,9 @@ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" } }, "hoek": { @@ -5211,8 +5208,8 @@ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "hosted-git-info": { @@ -5228,7 +5225,7 @@ "depd": "1.1.1", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" + "statuses": "1.4.0" }, "dependencies": { "depd": { @@ -5248,9 +5245,9 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" } }, "https-browserify": { @@ -5264,12 +5261,12 @@ "integrity": "sha1-LYzxwkciYCwgQdAbpq5eqlE4jw4=", "dev": true, "requires": { - "debug": "*", - "make-plural": "^3.0.3", - "math-interval-parser": "^1.1.0", - "messageformat": "^0.3.1", - "mustache": "*", - "sprintf-js": ">=1.0.3" + "debug": "2.6.9", + "make-plural": "3.0.6", + "math-interval-parser": "1.1.0", + "messageformat": "0.3.1", + "mustache": "2.3.0", + "sprintf-js": "1.0.3" } }, "iconv-lite": { @@ -5294,8 +5291,8 @@ "integrity": "sha1-2ln7hYl25KXkNwLM0fKC/byeV1Y=", "dev": true, "requires": { - "editions": "^1.3.3", - "ignorepatterns": "^1.1.0" + "editions": "1.3.4", + "ignorepatterns": "1.1.0" } }, "ignorepatterns": { @@ -5325,8 +5322,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -5344,7 +5341,7 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", "requires": { - "loose-envify": "^1.0.0" + "loose-envify": "1.3.1" } }, "invert-kv": { @@ -5362,7 +5359,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-arrayish": { @@ -5375,7 +5372,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { @@ -5388,7 +5385,7 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { - "builtin-modules": "^1.0.0" + "builtin-modules": "1.1.1" } }, "is-callable": { @@ -5401,7 +5398,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-date-object": { @@ -5414,9 +5411,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" }, "dependencies": { "kind-of": { @@ -5438,7 +5435,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "^2.0.0" + "is-primitive": "2.0.0" } }, "is-extendable": { @@ -5452,7 +5449,7 @@ "integrity": "sha1-JE4UDfdbscmjEG9BL/GC+1NKbWI=", "dev": true, "requires": { - "extended": "~0.0.3" + "extended": "0.0.6" } }, "is-extglob": { @@ -5466,7 +5463,7 @@ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-fn": { @@ -5490,7 +5487,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "is-hex-prefixed": { @@ -5504,7 +5501,7 @@ "integrity": "sha1-n69ltvttskt/XAYoR16nH5iEAeI=", "dev": true, "requires": { - "define-properties": "^1.1.1" + "define-properties": "1.1.2" } }, "is-natural-number": { @@ -5518,7 +5515,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-obj": { @@ -5537,7 +5534,7 @@ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", "requires": { - "is-number": "^4.0.0" + "is-number": "4.0.0" }, "dependencies": { "is-number": { @@ -5559,7 +5556,7 @@ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { - "is-path-inside": "^1.0.0" + "is-path-inside": "1.0.1" } }, "is-path-inside": { @@ -5568,7 +5565,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "^1.0.1" + "path-is-inside": "1.0.2" } }, "is-plain-obj": { @@ -5581,7 +5578,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -5614,7 +5611,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "requires": { - "has": "^1.0.1" + "has": "1.0.1" } }, "is-resolvable": { @@ -5678,8 +5675,8 @@ "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "dev": true, "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.3" } }, "isstream": { @@ -5693,20 +5690,20 @@ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.11", + "js-yaml": "3.11.0", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.3.0", + "wordwrap": "1.0.0" }, "dependencies": { "esprima": { @@ -5721,11 +5718,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "has-flag": { @@ -5746,7 +5743,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "1.0.0" } } } @@ -5756,8 +5753,8 @@ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" + "has-to-string-tag-x": "1.4.1", + "is-object": "1.0.1" } }, "js-sha3": { @@ -5781,8 +5778,8 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "1.0.10", + "esprima": "4.0.0" } }, "jsbn": { @@ -5806,11 +5803,11 @@ "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.6.1.tgz", "integrity": "sha512-xYuD9M1pcld5OKPzVAoEG5MKtnR8iKMyNzRpeS3/mCJ7dcAcS67vqfOmYLoaIQfVRU5uClThbjri3VFR0vEwYg==", "requires": { - "async": "^2.0.1", - "babel-preset-env": "^1.3.2", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0" + "async": "2.6.0", + "babel-preset-env": "1.6.1", + "babelify": "7.3.0", + "json-rpc-error": "2.0.0", + "promise-to-callback": "1.0.0" }, "dependencies": { "async": { @@ -5818,7 +5815,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } } } @@ -5828,7 +5825,7 @@ "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", "requires": { - "inherits": "^2.0.1" + "inherits": "2.0.3" } }, "json-rpc-random-id": { @@ -5851,7 +5848,7 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json-stable-stringify-without-jsonify": { @@ -5885,7 +5882,7 @@ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "jsonify": { @@ -5909,10 +5906,10 @@ "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", "requires": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" + "bindings": "1.3.0", + "inherits": "2.0.3", + "nan": "2.9.2", + "safe-buffer": "5.1.1" } }, "keccakjs": { @@ -5920,8 +5917,8 @@ "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", "requires": { - "browserify-sha3": "^0.0.1", - "sha3": "^1.1.0" + "browserify-sha3": "0.0.1", + "sha3": "1.2.0" } }, "kind-of": { @@ -5929,7 +5926,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } }, "klaw": { @@ -5937,7 +5934,7 @@ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "requires": { - "graceful-fs": "^4.1.9" + "graceful-fs": "4.1.11" } }, "lazy-cache": { @@ -5950,7 +5947,7 @@ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "requires": { - "invert-kv": "^1.0.0" + "invert-kv": "1.0.0" } }, "lcov-parse": { @@ -5968,7 +5965,7 @@ "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", "requires": { - "errno": "~0.1.1" + "errno": "0.1.7" } }, "level-iterator-stream": { @@ -5976,10 +5973,10 @@ "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" + "inherits": "2.0.3", + "level-errors": "1.0.5", + "readable-stream": "1.1.14", + "xtend": "4.0.1" }, "dependencies": { "isarray": { @@ -5992,10 +5989,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -6010,8 +6007,8 @@ "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" + "readable-stream": "1.0.34", + "xtend": "2.1.2" }, "dependencies": { "isarray": { @@ -6024,10 +6021,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -6040,7 +6037,7 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", "requires": { - "object-keys": "~0.4.0" + "object-keys": "0.4.0" } } } @@ -6050,13 +6047,13 @@ "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" + "deferred-leveldown": "1.2.2", + "level-codec": "7.0.1", + "level-errors": "1.0.5", + "level-iterator-stream": "1.3.1", + "prr": "1.0.1", + "semver": "5.4.1", + "xtend": "4.0.1" }, "dependencies": { "semver": { @@ -6072,8 +6069,8 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "1.1.2", + "type-check": "0.3.2" } }, "loader-runner": { @@ -6086,9 +6083,9 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0" + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" } }, "locate-path": { @@ -6096,8 +6093,8 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "2.0.0", + "path-exists": "3.0.0" } }, "lodash": { @@ -6131,7 +6128,7 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "requires": { - "js-tokens": "^3.0.0" + "js-tokens": "3.0.2" } }, "lowercase-keys": { @@ -6144,8 +6141,8 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "pseudomap": "1.0.2", + "yallist": "2.1.2" } }, "lru-queue": { @@ -6154,7 +6151,7 @@ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", "dev": true, "requires": { - "es5-ext": "~0.10.2" + "es5-ext": "0.10.39" } }, "ltgt": { @@ -6167,7 +6164,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", "requires": { - "pify": "^3.0.0" + "pify": "3.0.0" } }, "make-plural": { @@ -6176,7 +6173,7 @@ "integrity": "sha1-IDOgO6wpC487uRJY9lud9+iwHKc=", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "1.2.0" }, "dependencies": { "minimist": { @@ -6198,7 +6195,7 @@ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "requires": { - "object-visit": "^1.0.0" + "object-visit": "1.0.1" } }, "math-interval-parser": { @@ -6207,7 +6204,7 @@ "integrity": "sha1-2+2lsGsySZc8bfYXD94jhvCv2JM=", "dev": true, "requires": { - "xregexp": "^2.0.0" + "xregexp": "2.0.0" } }, "md5.js": { @@ -6215,8 +6212,8 @@ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.3" }, "dependencies": { "hash-base": { @@ -6224,8 +6221,8 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } } } @@ -6240,7 +6237,7 @@ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "1.2.0" } }, "memdown": { @@ -6248,12 +6245,12 @@ "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" + "abstract-leveldown": "2.7.2", + "functional-red-black-tree": "1.0.1", + "immediate": "3.2.3", + "inherits": "2.0.3", + "ltgt": "2.2.0", + "safe-buffer": "5.1.1" }, "dependencies": { "abstract-leveldown": { @@ -6261,7 +6258,7 @@ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", "requires": { - "xtend": "~4.0.0" + "xtend": "4.0.1" } } } @@ -6272,14 +6269,14 @@ "integrity": "sha512-sprBu6nwxBWBvBOh5v2jcsGqiGLlL2xr2dLub3vR8dnE8YB17omwtm/0NSHl8jjNbcsJd5GMWJAnTSVe/O0Wfg==", "dev": true, "requires": { - "d": "1", - "es5-ext": "^0.10.30", - "es6-weak-map": "^2.0.2", - "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.2" + "d": "1.0.0", + "es5-ext": "0.10.39", + "es6-weak-map": "2.0.2", + "event-emitter": "0.3.5", + "is-promise": "2.1.0", + "lru-queue": "0.1.0", + "next-tick": "1.0.0", + "timers-ext": "0.1.3" } }, "memory-fs": { @@ -6287,8 +6284,8 @@ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" + "errno": "0.1.7", + "readable-stream": "2.3.5" } }, "memorystream": { @@ -6306,14 +6303,14 @@ "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", + "async": "1.5.2", + "ethereumjs-util": "5.1.5", "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" + "levelup": "1.3.9", + "memdown": "1.4.1", + "readable-stream": "2.3.5", + "rlp": "2.0.0", + "semaphore": "1.1.0" }, "dependencies": { "ethereumjs-util": { @@ -6321,13 +6318,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } } } @@ -6338,11 +6335,11 @@ "integrity": "sha1-5Y//gkXps5cXmeW0PbWLPpQX9aI=", "dev": true, "requires": { - "async": "~1.5.2", - "glob": "~6.0.4", - "make-plural": "~3.0.3", - "nopt": "~3.0.6", - "watchr": "~2.4.13" + "async": "1.5.2", + "glob": "6.0.4", + "make-plural": "3.0.6", + "nopt": "3.0.6", + "watchr": "2.4.13" }, "dependencies": { "glob": { @@ -6351,11 +6348,11 @@ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } } } @@ -6371,19 +6368,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" } }, "miller-rabin": { @@ -6391,8 +6388,8 @@ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "bn.js": "4.11.6", + "brorand": "1.1.0" } }, "mime": { @@ -6410,7 +6407,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "requires": { - "mime-db": "~1.33.0" + "mime-db": "1.33.0" } }, "mimic-fn": { @@ -6428,7 +6425,7 @@ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", "requires": { - "dom-walk": "^0.1.0" + "dom-walk": "0.1.1" } }, "minimalistic-assert": { @@ -6446,7 +6443,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -6459,8 +6456,8 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "for-in": "1.0.2", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -6468,7 +6465,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -6486,7 +6483,7 @@ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", "requires": { - "mkdirp": "*" + "mkdirp": "0.5.1" } }, "mocha": { @@ -6546,7 +6543,7 @@ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "has-flag": "2.0.0" } } } @@ -6568,7 +6565,7 @@ "integrity": "sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A==", "dev": true, "requires": { - "moment": ">= 2.9.0" + "moment": "2.22.2" } }, "mout": { @@ -6587,8 +6584,8 @@ "integrity": "sha512-HwJGEKPCpLlNlgGQA56CYh/Wsqa+c4JAq8+mheIgw7OK5T4QvNJqgp6TH8gZ4q4l1aiWeNat/H/MrFXmTuoFfQ==", "dev": true, "requires": { - "bs58": "^4.0.1", - "varint": "^5.0.0" + "bs58": "4.0.1", + "varint": "5.0.0" }, "dependencies": { "base-x": { @@ -6597,7 +6594,7 @@ "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.1" } }, "bs58": { @@ -6606,7 +6603,7 @@ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dev": true, "requires": { - "base-x": "^3.0.2" + "base-x": "3.0.4" } } } @@ -6628,9 +6625,9 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" + "any-promise": "1.3.0", + "object-assign": "4.1.1", + "thenify-all": "1.6.0" } }, "nan": { @@ -6648,18 +6645,18 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-odd": "^2.0.0", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-odd": "2.0.0", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "arr-diff": { @@ -6713,8 +6710,8 @@ "integrity": "sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw==", "dev": true, "requires": { - "clone": "2.x", - "lodash": "4.x" + "clone": "2.1.1", + "lodash": "4.17.5" }, "dependencies": { "clone": { @@ -6730,8 +6727,8 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" + "encoding": "0.1.12", + "is-stream": "1.1.0" } }, "node-libs-browser": { @@ -6739,28 +6736,28 @@ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^1.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", + "assert": "1.4.1", + "browserify-zlib": "0.2.0", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "domain-browser": "1.2.0", + "events": "1.1.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", "path-browserify": "0.0.0", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.5", + "stream-browserify": "2.0.1", + "stream-http": "2.8.2", + "string_decoder": "1.0.3", + "timers-browserify": "2.0.10", "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.10.3", + "url": "0.11.0", + "util": "0.10.3", "vm-browserify": "0.0.4" }, "dependencies": { @@ -6769,9 +6766,9 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "base64-js": "1.2.3", + "ieee754": "1.1.10", + "isarray": "1.0.0" } }, "process": { @@ -6787,9 +6784,9 @@ "integrity": "sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A==", "dev": true, "requires": { - "cron-parser": "^2.4.0", + "cron-parser": "2.5.0", "long-timeout": "0.1.1", - "sorted-array-functions": "^1.0.0" + "sorted-array-functions": "1.2.0" } }, "nopt": { @@ -6798,7 +6795,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1" + "abbrev": "1.0.9" } }, "normalize-package-data": { @@ -6806,10 +6803,10 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -6817,7 +6814,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "requires": { - "remove-trailing-separator": "^1.0.1" + "remove-trailing-separator": "1.1.0" } }, "npm-run-path": { @@ -6825,7 +6822,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { - "path-key": "^2.0.0" + "path-key": "2.0.1" } }, "number-is-nan": { @@ -6857,9 +6854,9 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" }, "dependencies": { "define-property": { @@ -6867,7 +6864,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -6878,9 +6875,9 @@ "integrity": "sha1-hP0j9WsVWCrrPoiwXLVdJDLWijM=", "dev": true, "requires": { - "array-extended": "~0.0.4", - "extended": "~0.0.3", - "is-extended": "~0.0.3" + "array-extended": "0.0.11", + "extended": "0.0.6", + "is-extended": "0.0.10" } }, "object-inspect": { @@ -6898,7 +6895,7 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "requires": { - "isobject": "^3.0.0" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6914,8 +6911,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "for-own": "0.1.5", + "is-extendable": "0.1.1" } }, "object.pick": { @@ -6923,7 +6920,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6938,7 +6935,7 @@ "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", "requires": { - "http-https": "^1.0.0" + "http-https": "1.0.0" } }, "on-finished": { @@ -6954,7 +6951,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "onetime": { @@ -6963,7 +6960,7 @@ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "1.2.0" } }, "openzeppelin-solidity": { @@ -6977,8 +6974,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "minimist": "0.0.8", + "wordwrap": "0.0.3" }, "dependencies": { "wordwrap": { @@ -6995,12 +6992,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" } }, "original-require": { @@ -7024,9 +7021,9 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" } }, "os-tmpdir": { @@ -7044,7 +7041,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "requires": { - "p-try": "^1.0.0" + "p-try": "1.0.0" } }, "p-locate": { @@ -7052,7 +7049,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "^1.1.0" + "p-limit": "1.2.0" } }, "p-try": { @@ -7070,11 +7067,11 @@ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" + "asn1.js": "4.10.1", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" } }, "parse-glob": { @@ -7083,10 +7080,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" } }, "parse-headers": { @@ -7094,7 +7091,7 @@ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", "requires": { - "for-each": "^0.3.2", + "for-each": "0.3.2", "trim": "0.0.1" } }, @@ -7154,11 +7151,11 @@ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.10" } }, "pegjs": { @@ -7192,7 +7189,7 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { - "pinkie": "^2.0.0" + "pinkie": "2.0.4" } }, "pkg-dir": { @@ -7201,7 +7198,7 @@ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { - "find-up": "^1.0.0" + "find-up": "1.1.2" }, "dependencies": { "find-up": { @@ -7210,8 +7207,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "path-exists": { @@ -7220,7 +7217,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } } } @@ -7281,7 +7278,7 @@ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, "requires": { - "asap": "~2.0.3" + "asap": "2.0.6" } }, "promise-to-callback": { @@ -7289,8 +7286,8 @@ "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", "requires": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" + "is-fn": "1.0.0", + "set-immediate-shim": "1.0.1" } }, "prop-types": { @@ -7299,8 +7296,8 @@ "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "dev": true, "requires": { - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" + "loose-envify": "1.3.1", + "object-assign": "4.1.1" } }, "proxy-addr": { @@ -7308,7 +7305,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.1.2", "ipaddr.js": "1.6.0" } }, @@ -7327,11 +7324,11 @@ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.6", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.6" } }, "punycode": { @@ -7349,9 +7346,9 @@ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.0.tgz", "integrity": "sha512-F3DkxxlY0AqD/rwe4YAwjRE2HjOkKW7TxsuteyrS/Jbwrxw887PqYBL4sWUJ9D/V1hmFns0SCD6FDyvlwo9RCQ==", "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "decode-uri-component": "0.2.0", + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" } }, "querystring": { @@ -7370,8 +7367,8 @@ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { "is-number": { @@ -7380,7 +7377,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -7389,7 +7386,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -7400,7 +7397,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -7410,7 +7407,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "requires": { - "safe-buffer": "^5.1.0" + "safe-buffer": "5.1.1" } }, "randomfill": { @@ -7418,8 +7415,8 @@ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "randombytes": "2.0.6", + "safe-buffer": "5.1.1" } }, "randomhex": { @@ -7449,10 +7446,10 @@ "integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==", "dev": true, "requires": { - "fbjs": "^0.8.16", - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.0" + "fbjs": "0.8.17", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.2" } }, "react-dom": { @@ -7461,10 +7458,10 @@ "integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==", "dev": true, "requires": { - "fbjs": "^0.8.16", - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.0" + "fbjs": "0.8.17", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.2" } }, "readable-stream": { @@ -7472,13 +7469,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" } }, "readdirp": { @@ -7486,10 +7483,10 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.5", + "set-immediate-shim": "1.0.1" } }, "readline-sync": { @@ -7502,7 +7499,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "requires": { - "resolve": "^1.1.6" + "resolve": "1.5.0" } }, "regenerate": { @@ -7520,9 +7517,9 @@ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" } }, "regex-cache": { @@ -7531,7 +7528,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "^0.1.3" + "is-equal-shallow": "0.1.3" } }, "regex-not": { @@ -7539,8 +7536,8 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" } }, "regexpp": { @@ -7554,9 +7551,9 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "regenerate": "1.3.3", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" } }, "regjsgen": { @@ -7569,7 +7566,7 @@ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "requires": { - "jsesc": "~0.5.0" + "jsesc": "0.5.0" } }, "remove-trailing-separator": { @@ -7592,7 +7589,7 @@ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "requires": { - "is-finite": "^1.0.0" + "is-finite": "1.0.2" } }, "req-cwd": { @@ -7601,7 +7598,7 @@ "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", "dev": true, "requires": { - "req-from": "^1.0.1" + "req-from": "1.0.1" } }, "req-from": { @@ -7610,7 +7607,7 @@ "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", "dev": true, "requires": { - "resolve-from": "^2.0.0" + "resolve-from": "2.0.0" } }, "request": { @@ -7618,28 +7615,28 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "hawk": "~6.0.2", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "stringstream": "~0.0.5", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" } }, "require-directory": { @@ -7663,8 +7660,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "caller-path": "0.1.0", + "resolve-from": "1.0.1" }, "dependencies": { "resolve-from": { @@ -7680,7 +7677,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "requires": { - "path-parse": "^1.0.5" + "path-parse": "1.0.5" } }, "resolve-from": { @@ -7700,8 +7697,8 @@ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "onetime": "2.0.1", + "signal-exit": "3.0.2" } }, "resumer": { @@ -7709,7 +7706,7 @@ "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", "requires": { - "through": "~2.3.4" + "through": "2.3.8" } }, "ret": { @@ -7722,7 +7719,7 @@ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "requires": { - "align-text": "^0.1.1" + "align-text": "0.1.4" } }, "rimraf": { @@ -7735,8 +7732,8 @@ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", "requires": { - "hash-base": "^2.0.0", - "inherits": "^2.0.1" + "hash-base": "2.0.2", + "inherits": "2.0.3" } }, "rlp": { @@ -7750,7 +7747,7 @@ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { - "is-promise": "^2.1.0" + "is-promise": "2.1.0" } }, "rustbn.js": { @@ -7770,7 +7767,7 @@ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "dev": true, "requires": { - "rx-lite": "*" + "rx-lite": "4.0.8" } }, "safe": { @@ -7789,7 +7786,7 @@ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { - "ret": "~0.1.10" + "ret": "0.1.15" } }, "safefs": { @@ -7798,7 +7795,7 @@ "integrity": "sha1-gXDBRE1wOOCMrqBaN0+uL6NJ4Vw=", "dev": true, "requires": { - "graceful-fs": "*" + "graceful-fs": "4.1.11" } }, "scandirectory": { @@ -7807,9 +7804,9 @@ "integrity": "sha1-bOA/VKCQtmjjy+2/IO354xBZPnI=", "dev": true, "requires": { - "ignorefs": "^1.0.0", - "safefs": "^3.1.2", - "taskgroup": "^4.0.5" + "ignorefs": "1.2.0", + "safefs": "3.2.2", + "taskgroup": "4.3.1" } }, "scrypt": { @@ -7817,7 +7814,7 @@ "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", "requires": { - "nan": "^2.0.8" + "nan": "2.9.2" } }, "scrypt-async": { @@ -7836,8 +7833,8 @@ "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", "requires": { - "scrypt": "^6.0.2", - "scryptsy": "^1.2.1" + "scrypt": "6.0.3", + "scryptsy": "1.2.1" } }, "scryptsy": { @@ -7845,7 +7842,7 @@ "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", "requires": { - "pbkdf2": "^3.0.3" + "pbkdf2": "3.0.14" } }, "secp256k1": { @@ -7853,14 +7850,14 @@ "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", "requires": { - "bindings": "^1.2.1", - "bip66": "^1.1.3", - "bn.js": "^4.11.3", - "create-hash": "^1.1.2", - "drbg.js": "^1.0.1", - "elliptic": "^6.2.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" + "bindings": "1.3.0", + "bip66": "1.1.5", + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "drbg.js": "1.0.1", + "elliptic": "6.4.0", + "nan": "2.9.2", + "safe-buffer": "5.1.1" } }, "seek-bzip": { @@ -7868,7 +7865,7 @@ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", "requires": { - "commander": "~2.8.1" + "commander": "2.8.1" }, "dependencies": { "commander": { @@ -7876,7 +7873,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } } } @@ -7897,18 +7894,18 @@ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", + "http-errors": "1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" } }, "serve-static": { @@ -7916,9 +7913,9 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", "send": "0.16.2" } }, @@ -7927,11 +7924,11 @@ "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" + "body-parser": "1.18.2", + "cors": "2.8.4", + "express": "4.16.3", + "request": "2.85.0", + "xhr": "2.4.1" } }, "set-blocking": { @@ -7949,10 +7946,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" }, "dependencies": { "extend-shallow": { @@ -7960,7 +7957,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -7980,8 +7977,8 @@ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "sha3": { @@ -7989,7 +7986,7 @@ "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.0.tgz", "integrity": "sha1-aYnxtwpJhwWHajc+LGKs6WqpOZo=", "requires": { - "nan": "^2.0.5" + "nan": "2.9.2" } }, "shebang-command": { @@ -7997,7 +7994,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "1.0.0" } }, "shebang-regex": { @@ -8010,9 +8007,9 @@ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" } }, "signal-exit": { @@ -8030,9 +8027,9 @@ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz", "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==", "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "decompress-response": "3.3.0", + "once": "1.4.0", + "simple-concat": "1.0.0" } }, "slash": { @@ -8045,14 +8042,14 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.2", + "use": "3.1.0" }, "dependencies": { "define-property": { @@ -8060,7 +8057,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -8068,7 +8065,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -8078,9 +8075,9 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" }, "dependencies": { "define-property": { @@ -8088,7 +8085,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -8096,7 +8093,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -8104,7 +8101,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -8112,9 +8109,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -8134,7 +8131,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "requires": { - "kind-of": "^3.2.0" + "kind-of": "3.2.2" } }, "sntp": { @@ -8142,7 +8139,7 @@ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "requires": { - "hoek": "4.x.x" + "hoek": "4.2.1" } }, "sol-digger": { @@ -8163,12 +8160,12 @@ "integrity": "sha512-12Z84jxeb5VFlQOGS38HOiTrHYohU07oQ5wHOcFJmcRRbaL5kWN7IcldMO1QdW8kONyKdj0xhukzLlN5m5ix4w==", "dev": true, "requires": { - "bluebird": "^3.5.0", - "cli-color": "^1.2.0", - "commander": "^2.11.0", - "debug": "^3.0.1", - "fs-extra": "^4.0.2", - "glob": "^7.1.2" + "bluebird": "3.5.1", + "cli-color": "1.2.0", + "commander": "2.14.1", + "debug": "3.1.0", + "fs-extra": "4.0.3", + "glob": "7.1.2" }, "dependencies": { "debug": { @@ -8187,11 +8184,11 @@ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" + "fs-extra": "0.30.0", + "memorystream": "0.3.1", + "require-from-string": "1.2.1", + "semver": "5.5.0", + "yargs": "4.8.1" }, "dependencies": { "camelcase": { @@ -8204,9 +8201,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" } }, "find-up": { @@ -8214,8 +8211,8 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "fs-extra": { @@ -8223,11 +8220,11 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.2.8" } }, "is-fullwidth-code-point": { @@ -8235,7 +8232,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "jsonfile": { @@ -8243,7 +8240,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "load-json-file": { @@ -8251,11 +8248,11 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" } }, "os-locale": { @@ -8263,7 +8260,7 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { - "lcid": "^1.0.0" + "lcid": "1.0.0" } }, "parse-json": { @@ -8271,7 +8268,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "path-exists": { @@ -8279,7 +8276,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } }, "path-type": { @@ -8287,9 +8284,9 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "pify": { @@ -8302,9 +8299,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" } }, "read-pkg-up": { @@ -8312,8 +8309,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "1.1.2", + "read-pkg": "1.1.0" } }, "string-width": { @@ -8321,9 +8318,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "which-module": { @@ -8336,20 +8333,20 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "lodash.assign": "4.2.0", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "window-size": "0.2.0", + "y18n": "3.2.1", + "yargs-parser": "2.4.1" } }, "yargs-parser": { @@ -8357,8 +8354,8 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" + "camelcase": "3.0.0", + "lodash.assign": "4.2.0" } } } @@ -8369,21 +8366,20 @@ "integrity": "sha512-qikdsSi6+9XbfvwA0aI7HUVpF9fIFNqRWTw23M89GMDY+b6Gj0wWU9IngJS0fimoZIAdEp3bfChxvpfVcrUesg==", "dev": true, "requires": { - "death": "^1.1.0", + "death": "1.1.0", "ethereumjs-testrpc-sc": "6.1.6", - "istanbul": "^0.4.5", - "keccakjs": "^0.2.1", - "req-cwd": "^1.0.1", - "shelljs": "^0.7.4", - "sol-explore": "^1.6.2", + "istanbul": "0.4.5", + "keccakjs": "0.2.1", + "req-cwd": "1.0.1", + "shelljs": "0.7.8", + "sol-explore": "1.6.2", "solidity-parser-sc": "0.4.11", - "tree-kill": "^1.2.0", - "web3": "^0.18.4" + "tree-kill": "1.2.0", + "web3": "0.18.4" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "dev": true }, "shelljs": { @@ -8392,9 +8388,9 @@ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true, "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" } }, "sol-explore": { @@ -8410,10 +8406,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" + "crypto-js": "3.1.8", + "utf8": "2.1.1", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" } } } @@ -8424,13 +8420,13 @@ "integrity": "sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g==", "dev": true, "requires": { - "commander": "^2.14.1", - "lodash": "^4.17.5", - "mocha": "^5.0.1", - "mustache": "^2.3.0", - "react": "^16.2.0", - "react-dom": "^16.2.0", - "shelljs": "^0.8.1" + "commander": "2.14.1", + "lodash": "4.17.5", + "mocha": "5.2.0", + "mustache": "2.3.0", + "react": "16.4.2", + "react-dom": "16.4.2", + "shelljs": "0.8.2" }, "dependencies": { "browser-stdout": { @@ -8489,9 +8485,9 @@ "integrity": "sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw==", "dev": true, "requires": { - "mocha": "^4.1.0", - "pegjs": "^0.10.0", - "yargs": "^4.6.0" + "mocha": "4.1.0", + "pegjs": "0.10.0", + "yargs": "4.8.1" }, "dependencies": { "camelcase": { @@ -8506,9 +8502,9 @@ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" } }, "find-up": { @@ -8517,8 +8513,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "is-fullwidth-code-point": { @@ -8527,7 +8523,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "load-json-file": { @@ -8536,11 +8532,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" } }, "os-locale": { @@ -8549,7 +8545,7 @@ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { - "lcid": "^1.0.0" + "lcid": "1.0.0" } }, "parse-json": { @@ -8558,7 +8554,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "path-exists": { @@ -8567,7 +8563,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } }, "path-type": { @@ -8576,9 +8572,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "pify": { @@ -8593,9 +8589,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" } }, "read-pkg-up": { @@ -8604,8 +8600,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "1.1.2", + "read-pkg": "1.1.0" } }, "string-width": { @@ -8614,9 +8610,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "which-module": { @@ -8631,20 +8627,20 @@ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "dev": true, "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "lodash.assign": "4.2.0", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "window-size": "0.2.0", + "y18n": "3.2.1", + "yargs-parser": "2.4.1" } }, "yargs-parser": { @@ -8653,8 +8649,8 @@ "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "dev": true, "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" + "camelcase": "3.0.0", + "lodash.assign": "4.2.0" } } } @@ -8665,17 +8661,17 @@ "integrity": "sha512-hCZr5cEK2H6LVC1Lr7IGPGJ8Bs4Ktif9cmwnk3BHpoZLIwTtrNE0LUtTRBxkO3/G0GGB4OdxnnJT1pbgsJ/2Uw==", "dev": true, "requires": { - "ajv": "^5.2.2", - "chokidar": "^1.6.0", - "colors": "^1.1.2", - "commander": "^2.9.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.14.2", + "ajv": "5.5.2", + "chokidar": "1.7.0", + "colors": "1.2.1", + "commander": "2.14.1", + "js-string-escape": "1.0.1", + "lodash": "4.17.5", "sol-digger": "0.0.2", "sol-explore": "1.6.1", "solium-plugin-security": "0.1.1", "solparse": "2.2.4", - "text-table": "^0.2.0" + "text-table": "0.2.0" } }, "solium-plugin-security": { @@ -8690,9 +8686,9 @@ "integrity": "sha512-Sdyk983juUaOITdTD9U5Yc+MaX8kz4pN3wFyCRILWXW3+Ff96PxY9RLBuZINYbBgCAXN1a+kThJfFMlaXG9R6A==", "dev": true, "requires": { - "mocha": "^4.0.1", - "pegjs": "^0.10.0", - "yargs": "^10.0.3" + "mocha": "4.1.0", + "pegjs": "0.10.0", + "yargs": "10.1.2" }, "dependencies": { "commander": { @@ -8752,7 +8748,7 @@ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "has-flag": "2.0.0" } }, "yargs": { @@ -8761,18 +8757,18 @@ "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" + "cliui": "4.0.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "8.1.0" } }, "yargs-parser": { @@ -8781,7 +8777,7 @@ "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "4.1.0" } } } @@ -8807,11 +8803,11 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "atob": "2.1.1", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" } }, "source-map-support": { @@ -8819,7 +8815,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "requires": { - "source-map": "^0.5.6" + "source-map": "0.5.7" } }, "source-map-url": { @@ -8832,8 +8828,8 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, "spdx-exceptions": { @@ -8846,8 +8842,8 @@ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" } }, "spdx-license-ids": { @@ -8860,7 +8856,7 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "requires": { - "extend-shallow": "^3.0.0" + "extend-shallow": "3.0.2" } }, "sprintf-js": { @@ -8873,14 +8869,14 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" } }, "stack-trace": { @@ -8894,8 +8890,8 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "define-property": "0.2.5", + "object-copy": "0.1.0" }, "dependencies": { "define-property": { @@ -8903,7 +8899,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -8924,8 +8920,8 @@ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" + "inherits": "2.0.3", + "readable-stream": "2.3.5" } }, "stream-http": { @@ -8933,11 +8929,11 @@ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" }, "dependencies": { "readable-stream": { @@ -8945,13 +8941,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "string_decoder": { @@ -8959,7 +8955,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } } } @@ -8975,10 +8971,10 @@ "integrity": "sha1-dBlX3/SHsCcqee7FpE8jnubxfM0=", "dev": true, "requires": { - "array-extended": "~0.0.5", - "date-extended": "~0.0.3", - "extended": "~0.0.3", - "is-extended": "~0.0.3" + "array-extended": "0.0.11", + "date-extended": "0.0.6", + "extended": "0.0.6", + "is-extended": "0.0.10" } }, "string-width": { @@ -8986,8 +8982,8 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" }, "dependencies": { "ansi-regex": { @@ -9000,7 +8996,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "3.0.0" } } } @@ -9010,9 +9006,9 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" + "define-properties": "1.1.2", + "es-abstract": "1.10.0", + "function-bind": "1.1.1" } }, "string_decoder": { @@ -9020,7 +9016,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } }, "stringstream": { @@ -9033,7 +9029,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-bom": { @@ -9041,7 +9037,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "strip-dirs": { @@ -9049,7 +9045,7 @@ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", "requires": { - "is-natural-number": "^4.0.1" + "is-natural-number": "4.0.1" } }, "strip-eof": { @@ -9076,7 +9072,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } }, "swarm-js": { @@ -9084,19 +9080,19 @@ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "decompress": "^4.0.0", - "eth-lib": "^0.1.26", - "fs-extra": "^2.1.2", - "fs-promise": "^2.0.0", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar.gz": "^1.0.5", - "xhr-request-promise": "^0.1.2" + "bluebird": "3.5.1", + "buffer": "5.1.0", + "decompress": "4.2.0", + "eth-lib": "0.1.27", + "fs-extra": "2.1.2", + "fs-promise": "2.0.3", + "got": "7.1.0", + "mime-types": "2.1.18", + "mkdirp-promise": "5.0.1", + "mock-fs": "4.4.2", + "setimmediate": "1.0.5", + "tar.gz": "1.0.7", + "xhr-request-promise": "0.1.2" }, "dependencies": { "fs-extra": { @@ -9104,8 +9100,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0" } }, "got": { @@ -9113,20 +9109,20 @@ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" + "decompress-response": "3.3.0", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-plain-obj": "1.1.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "isurl": "1.0.0", + "lowercase-keys": "1.0.0", + "p-cancelable": "0.3.0", + "p-timeout": "1.2.1", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "url-parse-lax": "1.0.0", + "url-to-options": "1.0.1" } }, "jsonfile": { @@ -9134,7 +9130,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "p-cancelable": { @@ -9147,7 +9143,7 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", "requires": { - "p-finally": "^1.0.0" + "p-finally": "1.0.0" } }, "prepend-http": { @@ -9160,7 +9156,7 @@ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "requires": { - "prepend-http": "^1.0.1" + "prepend-http": "1.0.4" } } } @@ -9171,12 +9167,12 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", + "ajv": "5.5.2", + "ajv-keywords": "2.1.1", + "chalk": "2.3.2", + "lodash": "4.17.5", "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "string-width": "2.1.1" }, "dependencies": { "ansi-styles": { @@ -9185,7 +9181,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.1" } }, "chalk": { @@ -9194,9 +9190,9 @@ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.0" } }, "slice-ansi": { @@ -9205,7 +9201,7 @@ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0" + "is-fullwidth-code-point": "2.0.0" } }, "supports-color": { @@ -9214,7 +9210,7 @@ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -9224,19 +9220,19 @@ "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.0.tgz", "integrity": "sha512-j0jO9BiScfqtPBb9QmPLL0qvxXMz98xjkMb7x8lKipFlJZwNJkqkWPou+NU4V6T9RnVh1kuSthLE8gLrN8bBfw==", "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.2", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.1", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.5.0", - "resolve": "~1.5.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" + "deep-equal": "1.0.1", + "defined": "1.0.0", + "for-each": "0.3.2", + "function-bind": "1.1.1", + "glob": "7.1.2", + "has": "1.0.1", + "inherits": "2.0.3", + "minimist": "1.2.0", + "object-inspect": "1.5.0", + "resolve": "1.5.0", + "resumer": "0.0.0", + "string.prototype.trim": "1.1.2", + "through": "2.3.8" }, "dependencies": { "minimist": { @@ -9251,9 +9247,9 @@ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" } }, "tar-stream": { @@ -9261,10 +9257,10 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", "requires": { - "bl": "^1.0.0", - "end-of-stream": "^1.0.0", - "readable-stream": "^2.0.0", - "xtend": "^4.0.0" + "bl": "1.2.2", + "end-of-stream": "1.4.1", + "readable-stream": "2.3.5", + "xtend": "4.0.1" } }, "tar.gz": { @@ -9272,11 +9268,11 @@ "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", "requires": { - "bluebird": "^2.9.34", - "commander": "^2.8.1", - "fstream": "^1.0.8", - "mout": "^0.11.0", - "tar": "^2.1.1" + "bluebird": "2.11.0", + "commander": "2.14.1", + "fstream": "1.0.11", + "mout": "0.11.1", + "tar": "2.2.1" }, "dependencies": { "bluebird": { @@ -9292,8 +9288,8 @@ "integrity": "sha1-feGT/r12gnPEV3MElwJNUSwnkVo=", "dev": true, "requires": { - "ambi": "^2.2.0", - "csextends": "^1.0.3" + "ambi": "2.5.0", + "csextends": "1.2.0" } }, "text-table": { @@ -9307,7 +9303,7 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", "requires": { - "any-promise": "^1.0.0" + "any-promise": "1.3.0" } }, "thenify-all": { @@ -9315,7 +9311,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", "requires": { - "thenify": ">= 3.1.0 < 4" + "thenify": "3.3.0" } }, "through": { @@ -9333,7 +9329,7 @@ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "requires": { - "setimmediate": "^1.0.4" + "setimmediate": "1.0.5" } }, "timers-ext": { @@ -9342,8 +9338,8 @@ "integrity": "sha512-2iKErlS+NnEr0aQVQS91/mjsqCDO4OFl+5c5RDNtP+acQJTySvNSdbiSbmBD0t2RbErirF2Vq7x5YPQOSva77Q==", "dev": true, "requires": { - "es5-ext": "~0.10.14", - "next-tick": "1" + "es5-ext": "0.10.39", + "next-tick": "1.0.0" } }, "tingodb": { @@ -9352,10 +9348,10 @@ "integrity": "sha1-9jM2JZr336bJDf4lVqDfsNTu3lk=", "dev": true, "requires": { - "bson": "^1.0.4", - "lodash": "^4.17.5", - "safe": "^0.4.5", - "safe-buffer": "^5.1.1" + "bson": "1.0.9", + "lodash": "4.17.5", + "safe": "0.4.6", + "safe-buffer": "5.1.1" } }, "tmp": { @@ -9364,7 +9360,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "os-tmpdir": "1.0.2" } }, "to-arraybuffer": { @@ -9382,7 +9378,7 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "to-regex": { @@ -9390,10 +9386,10 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" } }, "to-regex-range": { @@ -9401,8 +9397,8 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "3.0.0", + "repeat-string": "1.6.1" }, "dependencies": { "is-number": { @@ -9410,7 +9406,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } } } @@ -9420,7 +9416,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "requires": { - "punycode": "^1.4.1" + "punycode": "1.4.1" } }, "tree-kill": { @@ -9445,7 +9441,7 @@ "integrity": "sha1-vydYaYi0/4RWPt+/MrR5QUCKdq0=", "dev": true, "requires": { - "mocha": "^4.1.0", + "mocha": "4.1.0", "original-require": "1.0.1", "solc": "0.4.24" } @@ -9461,15 +9457,14 @@ "integrity": "sha512-/1LCtJFf5Jvm5Rv88T0d/rZSKvaiW/yO1SHXLGJgKzLsiG1F/2spFs4HrI1mRxP00opfrYXloEmLtkVV/kcndQ==", "requires": { "ethjs-abi": "0.1.8", - "truffle-blockchain-utils": "^0.0.4", - "truffle-contract-schema": "^2.0.0", + "truffle-blockchain-utils": "0.0.4", + "truffle-contract-schema": "2.0.0", "truffle-error": "0.0.2", - "web3": "^0.20.1" + "web3": "0.20.6" }, "dependencies": { "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" }, "ethjs-abi": { "version": "0.1.8", @@ -9487,10 +9482,10 @@ "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" + "crypto-js": "3.1.8", + "utf8": "2.1.1", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" } } } @@ -9500,9 +9495,9 @@ "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-2.0.0.tgz", "integrity": "sha512-nLlspmu1GKDaluWksBwitHi/7Z3IpRjmBYeO9N+T1nVJD2V4IWJaptCKP1NqnPiJA+FChB7+F7pI6Br51/FtXQ==", "requires": { - "ajv": "^5.1.1", - "crypto-js": "^3.1.9-1", - "debug": "^3.1.0" + "ajv": "5.5.2", + "crypto-js": "3.1.9-1", + "debug": "3.1.0" }, "dependencies": { "crypto-js": { @@ -9530,10 +9525,10 @@ "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.1.0.tgz", "integrity": "sha512-Vj04yr2d9qLRZspoHztbE/YQnVaoFb90JNZHtggRUm+JFm/NOiSJHLVI63+3mtUIuQ04EuKZ7Df8JQw0Ni7IeA==", "requires": { - "ethereumjs-tx": "^1.3.3", - "ethereumjs-wallet": "^0.6.0", - "web3": "^0.20.5", - "web3-provider-engine": "^13.6.4" + "ethereumjs-tx": "1.3.4", + "ethereumjs-wallet": "0.6.0", + "web3": "0.20.6", + "web3-provider-engine": "13.6.6" }, "dependencies": { "async": { @@ -9541,12 +9536,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } }, "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" }, "clone": { "version": "2.1.2", @@ -9558,13 +9552,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } }, "web3": { @@ -9573,10 +9567,10 @@ "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" + "crypto-js": "3.1.8", + "utf8": "2.1.1", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" } }, "web3-provider-engine": { @@ -9584,25 +9578,25 @@ "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.6.6.tgz", "integrity": "sha512-M9eztIxwCR2U7+d42RXdu3fBjvG/kcv7Ra8z2PHs912aHhAkMtNfvzhC8dboC7yKmj230eVHwouSXKizmSqC7Q==", "requires": { - "async": "^2.5.0", - "clone": "^2.0.0", - "eth-block-tracker": "^2.2.2", - "eth-sig-util": "^1.4.2", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.1", - "ethereumjs-vm": "^2.0.2", - "fetch-ponyfill": "^4.0.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.67.0", - "semaphore": "^1.0.3", - "solc": "^0.4.2", - "tape": "^4.4.0", - "xhr": "^2.2.0", - "xtend": "^4.0.1" + "async": "2.6.0", + "clone": "2.1.2", + "eth-block-tracker": "2.3.0", + "eth-sig-util": "1.4.2", + "ethereumjs-block": "1.7.1", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.1.5", + "ethereumjs-vm": "2.3.3", + "fetch-ponyfill": "4.1.0", + "json-rpc-error": "2.0.0", + "json-stable-stringify": "1.0.1", + "promise-to-callback": "1.0.0", + "readable-stream": "2.3.5", + "request": "2.85.0", + "semaphore": "1.1.0", + "solc": "0.4.24", + "tape": "4.9.0", + "xhr": "2.4.1", + "xtend": "4.0.1" } } } @@ -9613,14 +9607,13 @@ "integrity": "sha1-21nOb6HFWHZgERN1CalN/KjRQI4=", "dev": true, "requires": { - "ethereumjs-wallet": "^0.6.0", - "web3": "^0.18.2", - "web3-provider-engine": "^8.4.0" + "ethereumjs-wallet": "0.6.0", + "web3": "0.18.4", + "web3-provider-engine": "8.6.1" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "dev": true }, "web3": { @@ -9630,10 +9623,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" + "crypto-js": "3.1.8", + "utf8": "2.1.1", + "xhr2": "0.1.4", + "xmlhttprequest": "1.8.0" } } } @@ -9648,7 +9641,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.1" } }, "tweetnacl": { @@ -9663,7 +9656,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "1.1.2" } }, "type-is": { @@ -9672,7 +9665,7 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "2.1.18" } }, "typechecker": { @@ -9692,7 +9685,7 @@ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "requires": { - "is-typedarray": "^1.0.0" + "is-typedarray": "1.0.0" } }, "ua-parser-js": { @@ -9706,9 +9699,9 @@ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" }, "dependencies": { "camelcase": { @@ -9721,8 +9714,8 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", + "center-align": "0.1.3", + "right-align": "0.1.3", "wordwrap": "0.0.2" } }, @@ -9741,9 +9734,9 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", "window-size": "0.1.0" } } @@ -9760,9 +9753,9 @@ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", "requires": { - "source-map": "^0.5.6", - "uglify-js": "^2.8.29", - "webpack-sources": "^1.0.1" + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.1.0" } }, "ultron": { @@ -9775,8 +9768,8 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", "requires": { - "buffer": "^3.0.1", - "through": "^2.3.6" + "buffer": "3.6.0", + "through": "2.3.8" }, "dependencies": { "base64-js": { @@ -9790,8 +9783,8 @@ "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", "requires": { "base64-js": "0.0.8", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "ieee754": "1.1.10", + "isarray": "1.0.0" } } } @@ -9801,10 +9794,10 @@ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" }, "dependencies": { "extend-shallow": { @@ -9812,7 +9805,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "set-value": { @@ -9820,10 +9813,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" } } } @@ -9850,8 +9843,8 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" + "has-value": "0.3.1", + "isobject": "3.0.1" }, "dependencies": { "has-value": { @@ -9859,9 +9852,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" }, "dependencies": { "isobject": { @@ -9896,7 +9889,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", "requires": { - "punycode": "^2.1.0" + "punycode": "2.1.0" }, "dependencies": { "punycode": { @@ -9942,7 +9935,7 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "requires": { - "kind-of": "^6.0.2" + "kind-of": "6.0.2" }, "dependencies": { "kind-of": { @@ -9998,8 +9991,8 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "varint": { @@ -10018,9 +10011,9 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "^1.0.0", + "assert-plus": "1.0.0", "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "extsprintf": "1.3.0" } }, "vm-browserify": { @@ -10036,9 +10029,9 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "chokidar": "2.0.3", + "graceful-fs": "4.1.11", + "neo-async": "2.5.0" }, "dependencies": { "anymatch": { @@ -10046,8 +10039,8 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "micromatch": "3.1.10", + "normalize-path": "2.1.1" } }, "arr-diff": { @@ -10065,16 +10058,16 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" }, "dependencies": { "extend-shallow": { @@ -10082,7 +10075,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -10092,18 +10085,18 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.1.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.0" + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.2", + "fsevents": "1.1.3", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.0.5" } }, "expand-brackets": { @@ -10111,13 +10104,13 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -10125,7 +10118,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -10133,7 +10126,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "is-accessor-descriptor": { @@ -10141,7 +10134,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -10149,7 +10142,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -10159,7 +10152,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -10167,7 +10160,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -10177,9 +10170,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" } }, "kind-of": { @@ -10194,14 +10187,14 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -10209,7 +10202,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "extend-shallow": { @@ -10217,7 +10210,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -10227,10 +10220,10 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" }, "dependencies": { "extend-shallow": { @@ -10238,7 +10231,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -10248,8 +10241,8 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" }, "dependencies": { "is-glob": { @@ -10257,7 +10250,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } } } @@ -10267,7 +10260,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -10275,7 +10268,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -10283,9 +10276,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "is-extglob": { @@ -10298,7 +10291,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "requires": { - "is-extglob": "^2.1.1" + "is-extglob": "2.1.1" } }, "is-number": { @@ -10306,7 +10299,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -10314,7 +10307,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -10334,19 +10327,19 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" } } } @@ -10357,14 +10350,14 @@ "integrity": "sha1-10hHu01vkPYf4sdPn2hmKqDgdgE=", "dev": true, "requires": { - "eachr": "^2.0.2", - "extendr": "^2.1.0", - "extract-opts": "^2.2.0", - "ignorefs": "^1.0.0", - "safefs": "^3.1.2", - "scandirectory": "^2.5.0", - "taskgroup": "^4.2.0", - "typechecker": "^2.0.8" + "eachr": "2.0.4", + "extendr": "2.1.0", + "extract-opts": "2.2.0", + "ignorefs": "1.2.0", + "safefs": "3.2.2", + "scandirectory": "2.5.0", + "taskgroup": "4.3.1", + "typechecker": "2.1.0" } }, "web3": { @@ -10396,20 +10389,20 @@ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" + "decompress-response": "3.3.0", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-plain-obj": "1.1.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "isurl": "1.0.0", + "lowercase-keys": "1.0.0", + "p-cancelable": "0.3.0", + "p-timeout": "1.2.1", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "url-parse-lax": "1.0.0", + "url-to-options": "1.0.1" } }, "p-cancelable": { @@ -10422,7 +10415,7 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", "requires": { - "p-finally": "^1.0.0" + "p-finally": "1.0.0" } }, "prepend-http": { @@ -10440,7 +10433,7 @@ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "requires": { - "prepend-http": "^1.0.1" + "prepend-http": "1.0.4" } } } @@ -10603,9 +10596,9 @@ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "bn.js": "4.11.6", + "elliptic": "6.4.0", + "xhr-request-promise": "0.1.2" } }, "underscore": { @@ -10679,20 +10672,20 @@ "integrity": "sha1-TYbhnjDKr5ffNRUR7A9gE25bMOs=", "dev": true, "requires": { - "async": "^2.1.2", - "clone": "^2.0.0", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.0.2", - "isomorphic-fetch": "^2.2.0", - "request": "^2.67.0", - "semaphore": "^1.0.3", - "solc": "^0.4.2", - "tape": "^4.4.0", - "web3": "^0.16.0", - "xhr": "^2.2.0", - "xtend": "^4.0.1" + "async": "2.6.0", + "clone": "2.1.1", + "ethereumjs-block": "1.7.1", + "ethereumjs-tx": "1.3.4", + "ethereumjs-util": "5.1.5", + "ethereumjs-vm": "2.3.3", + "isomorphic-fetch": "2.2.1", + "request": "2.85.0", + "semaphore": "1.1.0", + "solc": "0.4.24", + "tape": "4.9.0", + "web3": "0.16.0", + "xhr": "2.4.1", + "xtend": "4.0.1" }, "dependencies": { "async": { @@ -10701,12 +10694,11 @@ "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } }, "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", "dev": true }, "clone": { @@ -10721,13 +10713,13 @@ "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "dev": true, "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "bn.js": "4.11.6", + "create-hash": "1.1.3", + "ethjs-util": "0.1.4", + "keccak": "1.4.0", + "rlp": "2.0.0", + "safe-buffer": "5.1.1", + "secp256k1": "3.5.0" } }, "web3": { @@ -10737,9 +10729,9 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xmlhttprequest": "*" + "crypto-js": "3.1.8", + "utf8": "2.1.1", + "xmlhttprequest": "1.8.0" } } } @@ -10824,28 +10816,28 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz", "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", "requires": { - "acorn": "^5.0.0", - "acorn-dynamic-import": "^2.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "async": "^2.1.2", - "enhanced-resolve": "^3.4.0", - "escope": "^3.6.0", - "interpret": "^1.0.0", - "json-loader": "^0.5.4", - "json5": "^0.5.1", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "mkdirp": "~0.5.0", - "node-libs-browser": "^2.0.0", - "source-map": "^0.5.3", - "supports-color": "^4.2.1", - "tapable": "^0.2.7", - "uglifyjs-webpack-plugin": "^0.4.6", - "watchpack": "^1.4.0", - "webpack-sources": "^1.0.1", - "yargs": "^8.0.2" + "acorn": "5.5.3", + "acorn-dynamic-import": "2.0.2", + "ajv": "6.5.0", + "ajv-keywords": "3.2.0", + "async": "2.6.0", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.6.0", + "webpack-sources": "1.1.0", + "yargs": "8.0.2" }, "dependencies": { "ajv": { @@ -10853,10 +10845,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0", - "uri-js": "^4.2.1" + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1", + "uri-js": "4.2.1" } }, "ajv-keywords": { @@ -10869,7 +10861,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "^4.14.0" + "lodash": "4.17.5" } }, "cliui": { @@ -10877,9 +10869,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" }, "dependencies": { "string-width": { @@ -10887,9 +10879,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } } } @@ -10899,10 +10891,10 @@ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "object-assign": "^4.0.1", - "tapable": "^0.2.7" + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" } }, "fast-deep-equal": { @@ -10920,7 +10912,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "load-json-file": { @@ -10928,10 +10920,10 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" } }, "parse-json": { @@ -10939,7 +10931,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "path-type": { @@ -10947,7 +10939,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "requires": { - "pify": "^2.0.0" + "pify": "2.3.0" } }, "pify": { @@ -10960,9 +10952,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" } }, "read-pkg-up": { @@ -10970,8 +10962,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "find-up": "2.1.0", + "read-pkg": "2.0.0" } }, "strip-bom": { @@ -10984,7 +10976,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "requires": { - "has-flag": "^2.0.0" + "has-flag": "2.0.0" } }, "tapable": { @@ -10997,19 +10989,19 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" } }, "yargs-parser": { @@ -11017,7 +11009,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", "requires": { - "camelcase": "^4.1.0" + "camelcase": "4.1.0" } } } @@ -11027,8 +11019,8 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" + "source-list-map": "2.0.0", + "source-map": "0.6.1" }, "dependencies": { "source-map": { @@ -11040,12 +11032,11 @@ }, "websocket": { "version": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", - "from": "websocket@git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", "requires": { - "debug": "^2.2.0", - "nan": "^2.3.3", - "typedarray-to-buffer": "^3.1.2", - "yaeti": "^0.0.6" + "debug": "2.6.9", + "nan": "2.9.2", + "typedarray-to-buffer": "3.1.5", + "yaeti": "0.0.6" } }, "whatwg-fetch": { @@ -11059,7 +11050,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "which-module": { @@ -11078,12 +11069,12 @@ "integrity": "sha512-GYKuysPz2pxYAVJD2NPsDLP5Z79SDEzPm9/j4tCjkF/n89iBNGBMJcR+dMUqxgPNgoSs6fVygPi+Vl2oxIpBuw==", "dev": true, "requires": { - "async": "~1.0.0", - "colors": "1.0.x", - "cycle": "1.0.x", - "eyes": "0.1.x", - "isstream": "0.1.x", - "stack-trace": "0.0.x" + "async": "1.0.0", + "colors": "1.0.3", + "cycle": "1.0.3", + "eyes": "0.1.8", + "isstream": "0.1.2", + "stack-trace": "0.0.10" }, "dependencies": { "async": { @@ -11111,8 +11102,8 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "string-width": "1.0.2", + "strip-ansi": "3.0.1" }, "dependencies": { "is-fullwidth-code-point": { @@ -11120,7 +11111,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "string-width": { @@ -11128,9 +11119,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } } } @@ -11146,7 +11137,7 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "^0.5.1" + "mkdirp": "0.5.1" } }, "ws": { @@ -11154,9 +11145,9 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1", + "ultron": "1.1.1" } }, "xhr": { @@ -11164,10 +11155,10 @@ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.1.tgz", "integrity": "sha512-pAIU5vBr9Hiy5cpFIbPnwf0C18ZF86DBsZKrlsf87N5De/JbA6RJ83UP/cv+aljl4S40iRVMqP4pr4sF9Dnj0A==", "requires": { - "global": "~4.3.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" + "global": "4.3.2", + "is-function": "1.0.1", + "parse-headers": "2.0.1", + "xtend": "4.0.1" } }, "xhr-request": { @@ -11175,13 +11166,13 @@ "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" + "buffer-to-arraybuffer": "0.0.5", + "object-assign": "4.1.1", + "query-string": "5.1.0", + "simple-get": "2.7.0", + "timed-out": "4.0.1", + "url-set-query": "1.0.0", + "xhr": "2.4.1" } }, "xhr-request-promise": { @@ -11189,7 +11180,7 @@ "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", "requires": { - "xhr-request": "^1.0.1" + "xhr-request": "1.1.0" } }, "xhr2": { @@ -11234,18 +11225,18 @@ "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" + "cliui": "4.0.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" } }, "yargs-parser": { @@ -11254,7 +11245,7 @@ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "4.1.0" } }, "yauzl": { @@ -11262,8 +11253,8 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.0.1" + "buffer-crc32": "0.2.13", + "fd-slicer": "1.0.1" } } } diff --git a/test/w_volume_restriction_transfer_manager.js b/test/w_volume_restriction_transfer_manager.js index 868ec0de7..b117511c8 100644 --- a/test/w_volume_restriction_transfer_manager.js +++ b/test/w_volume_restriction_transfer_manager.js @@ -953,6 +953,7 @@ contract('VolumeRestrictionTransferManager', accounts => { // wait 4 seconds for the lockup's first period to elapse. await new Promise(resolve => setTimeout(resolve, 4000)); + // should succeed await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); @@ -996,16 +997,16 @@ contract('VolumeRestrictionTransferManager', accounts => { // should now be able to transfer 4, because of 2 allowed from the 1st lockup and 2 from the 2nd await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); - // try aother transfer. it should fail because it's locked up from both lockups again - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + // // try aother transfer. it should fail because it's locked up from both lockups again + // errorThrown = false; + // try { + // await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); + // } catch(error) { + // console.log(` tx revert -> couldn't transfer because of lock up`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); // wait 8 seconds for 2nd lockup's third and fourth periods to elapse await new Promise(resolve => setTimeout(resolve, 8000)); From 9c5667a5a6c73c68ae6a2b9c646308a704c445e7 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Fri, 5 Oct 2018 11:45:18 +0100 Subject: [PATCH 078/142] Add the ability to bypass issuance transfers --- .../PercentageTransferManager.sol | 28 +- .../SingleTradeVolumeRestrictionManager.sol | 313 +++++ ...leTradeVolumeRestrictionManagerFactory.sol | 114 ++ test/l_percentage_transfer_manager.js | 28 +- test/x_single_trade_volume_restriction.js | 1162 +++++++++++++++++ 5 files changed, 1638 insertions(+), 7 deletions(-) create mode 100644 contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol create mode 100644 contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol create mode 100644 test/x_single_trade_volume_restriction.js diff --git a/contracts/modules/TransferManager/PercentageTransferManager.sol b/contracts/modules/TransferManager/PercentageTransferManager.sol index de5b590a3..77b79639f 100644 --- a/contracts/modules/TransferManager/PercentageTransferManager.sol +++ b/contracts/modules/TransferManager/PercentageTransferManager.sol @@ -11,10 +11,14 @@ contract PercentageTransferManager is ITransferManager { // Permission key for modifying the whitelist bytes32 public constant WHITELIST = "WHITELIST"; + bytes32 public constant ADMIN = "ADMIN"; // Maximum percentage that any holder can have, multiplied by 10**16 - e.g. 20% is 20 * 10**16 uint256 public maxHolderPercentage; + // Ignore transactions which are part of the primary issuance + bool public allowPrimaryIssuance = true; + // Addresses on this list are always able to send / receive tokens mapping (address => bool) public whitelist; @@ -25,6 +29,7 @@ contract PercentageTransferManager is ITransferManager { address _addedBy, bool _valid ); + event SetAllowPrimaryIssuance(bool _allowPrimaryIssuance, uint256 _timestamp); /** * @notice Constructor @@ -38,8 +43,11 @@ contract PercentageTransferManager is ITransferManager { } /// @notice Used to verify the transfer transaction according to the rule implemented in the trnasfer managers - function verifyTransfer(address /* _from */, address _to, uint256 _amount, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { + function verifyTransfer(address _from, address _to, uint256 _amount, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { if (!paused) { + if (_from == address(0) && allowPrimaryIssuance) { + return Result.NA; + } // If an address is on the whitelist, it is allowed to hold more than maxHolderPercentage of the tokens. if (whitelist[_to]) { return Result.NA; @@ -57,15 +65,16 @@ contract PercentageTransferManager is ITransferManager { * @notice Used to intialize the variables of the contract * @param _maxHolderPercentage Maximum amount of ST20 tokens(in %) can hold by the investor */ - function configure(uint256 _maxHolderPercentage) public onlyFactory { + function configure(uint256 _maxHolderPercentage, bool _allowPrimaryIssuance) public onlyFactory { maxHolderPercentage = _maxHolderPercentage; + allowPrimaryIssuance = _allowPrimaryIssuance; } /** * @notice This function returns the signature of configure function */ function getInitFunction() public pure returns (bytes4) { - return bytes4(keccak256("configure(uint256)")); + return bytes4(keccak256("configure(uint256,bool)")); } /** @@ -99,12 +108,23 @@ contract PercentageTransferManager is ITransferManager { } } + /** + * @notice sets whether or not to consider primary issuance transfers + * @param _allowPrimaryIssuance whether to allow all primary issuance transfers + */ + function setAllowPrimaryIssuance(bool _allowPrimaryIssuance) public withPerm(ADMIN) { + require(_allowPrimaryIssuance != allowPrimaryIssuance, "Must change setting"); + allowPrimaryIssuance = _allowPrimaryIssuance; + emit SetAllowPrimaryIssuance(_allowPrimaryIssuance, now); + } + /** * @notice Return the permissions flag that are associated with Percentage transfer Manager */ function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); + bytes32[] memory allPermissions = new bytes32[](2); allPermissions[0] = WHITELIST; + allPermissions[1] = ADMIN; return allPermissions; } diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol new file mode 100644 index 000000000..c66ca8e26 --- /dev/null +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol @@ -0,0 +1,313 @@ +pragma solidity ^0.4.24; +import "./ITransferManager.sol"; +import "openzeppelin-solidity/contracts/math/SafeMath.sol"; + +/** + * @title Transfer Manager for limiting volume of tokens in a single trade + */ + +contract SingleTradeVolumeRestrictionManager is ITransferManager { + using SafeMath for uint256; + + bytes32 constant public ADMIN = "ADMIN"; + + bool public isTransferLimitInPercentage; + + uint256 public globalTransferLimitInTokens; + + // should be multipled by 10^16. if the transfer percentage is 20%, then globalTransferLimitInPercentage should be 20*10^16 + uint256 public globalTransferLimitInPercentage; + + // Ignore transactions which are part of the primary issuance + bool public allowPrimaryIssuance = true; + + //mapping to store the wallets that are exempted from the volume restriction + mapping(address => bool) public exemptWallets; + + //addresses on this list have special transfer restrictions apart from global + mapping(address => uint) public specialTransferLimitsInTokens; + + mapping(address => uint) public specialTransferLimitsInPercentages; + + event ExemptWalletAdded(address _wallet); + event ExemptWalletRemoved(address _wallet); + event TransferLimitInTokensSet(address _wallet, uint256 _amount); + event TransferLimitInPercentageSet(address _wallet, uint _percentage); + event TransferLimitInPercentageRemoved(address _wallet); + event TransferLimitInTokensRemoved(address _wallet); + event GlobalTransferLimitInTokensSet(uint256 _amount, uint256 _oldAmount); + event GlobalTransferLimitInPercentageSet(uint256 _percentage, uint256 _oldPercentage); + event TransferLimitChangedToTokens(); + event TransferLimitChangedtoPercentage(); + event SetAllowPrimaryIssuance(bool _allowPrimaryIssuance, uint256 _timestamp); + + /** + * @notice Constructor + * @param _securityToken Address of the security token + * @param _polyAddress Address of the polytoken + */ + constructor(address _securityToken, address _polyAddress) public + Module(_securityToken, _polyAddress) + { + + } + + /// @notice Used to verify the transfer transaction according to the rule implemented in the transfer manager + function verifyTransfer(address _from, address /* _to */, uint256 _amount, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { + bool validTransfer; + + if (exemptWallets[_from] || paused) return Result.NA; + + if (_from == address(0) && allowPrimaryIssuance) { + return Result.NA; + } + + if (isTransferLimitInPercentage) { + if(specialTransferLimitsInPercentages[_from] > 0) { + validTransfer = (_amount.mul(10**18).div(ISecurityToken(securityToken).totalSupply())) <= specialTransferLimitsInPercentages[_from]; + } else { + validTransfer = (_amount.mul(10**18).div(ISecurityToken(securityToken).totalSupply())) <= globalTransferLimitInPercentage; + } + } else { + if (specialTransferLimitsInTokens[_from] > 0) { + validTransfer = _amount <= specialTransferLimitsInTokens[_from]; + } else { + validTransfer = _amount <= globalTransferLimitInTokens; + } + } + if (validTransfer) return Result.NA; + return Result.INVALID; + } + + /** + * @notice Used to intialize the variables of the contract + * @param _isTransferLimitInPercentage true if the transfer limit is in percentage else false + * @param _globalTransferLimitInPercentageOrToken transfer limit per single transaction. + */ + function configure(bool _isTransferLimitInPercentage, uint256 _globalTransferLimitInPercentageOrToken, bool _allowPrimaryIssuance) public onlyFactory { + isTransferLimitInPercentage = _isTransferLimitInPercentage; + if (isTransferLimitInPercentage) { + changeGlobalLimitInPercentage(_globalTransferLimitInPercentageOrToken); + } else { + changeGlobalLimitInTokens(_globalTransferLimitInPercentageOrToken); + } + allowPrimaryIssuance = _allowPrimaryIssuance; + } + + /** + * @notice sets whether or not to consider primary issuance transfers + * @param _allowPrimaryIssuance whether to allow all primary issuance transfers + */ + function setAllowPrimaryIssuance(bool _allowPrimaryIssuance) public withPerm(ADMIN) { + require(_allowPrimaryIssuance != allowPrimaryIssuance, "Must change setting"); + allowPrimaryIssuance = _allowPrimaryIssuance; + emit SetAllowPrimaryIssuance(_allowPrimaryIssuance, now); + } + + /** + * @notice Changes the manager to use transfer limit as Percentages + * @param _newGlobalTransferLimitInPercentage uint256 new global Transfer Limit In Percentage. + * @dev specialTransferLimits set for wallets have to re-configured + */ + function changeTransferLimitToPercentage(uint256 _newGlobalTransferLimitInPercentage) public withPerm(ADMIN) { + require(!isTransferLimitInPercentage, "Transfer limit already in percentage"); + isTransferLimitInPercentage = true; + changeGlobalLimitInPercentage(_newGlobalTransferLimitInPercentage); + emit TransferLimitChangedtoPercentage(); + } + + /** + * @notice Changes the manager to use transfer limit as tokens + * @param _newGlobalTransferLimit uint256 new global Transfer Limit in tokens. + * @dev specialTransferLimits set for wallets have to re-configured + */ + function changeTransferLimitToTokens(uint _newGlobalTransferLimit) public withPerm(ADMIN) { + require(isTransferLimitInPercentage, "Transfer limit already in tokens"); + isTransferLimitInPercentage = false; + changeGlobalLimitInTokens(_newGlobalTransferLimit); + emit TransferLimitChangedToTokens(); + } + /** + * @notice Change the global transfer limit + * @param _newGlobalTransferLimitInTokens new transfer limit in tokens + * @dev This function can be used only when The manager is configured to use limits in tokens + */ + function changeGlobalLimitInTokens(uint256 _newGlobalTransferLimitInTokens) public withPerm(ADMIN) { + require(!isTransferLimitInPercentage, "Transfer limit not set in tokens"); + require(_newGlobalTransferLimitInTokens > 0, "Transfer limit has to greater than zero"); + emit GlobalTransferLimitInTokensSet(_newGlobalTransferLimitInTokens, globalTransferLimitInTokens); + globalTransferLimitInTokens = _newGlobalTransferLimitInTokens; + + } + + /** + * @notice Change the global transfer limit + * @param _newGlobalTransferLimitInPercentage new transfer limit in percentage. + * Multiply the percentage by 10^16. Eg 22% will be 22*10^16 + * @dev This function can be used only when The manager is configured to use limits in percentage + */ + function changeGlobalLimitInPercentage(uint256 _newGlobalTransferLimitInPercentage) public withPerm(ADMIN) { + require(isTransferLimitInPercentage, "Transfer limit not set in Percentage"); + require(_newGlobalTransferLimitInPercentage > 0 && _newGlobalTransferLimitInPercentage <= 100 * 10 ** 16); + emit GlobalTransferLimitInPercentageSet(_newGlobalTransferLimitInPercentage, globalTransferLimitInPercentage); + globalTransferLimitInPercentage = _newGlobalTransferLimitInPercentage; + + } + + /** + * @notice add an exempt wallet + * @param _wallet exempt wallet address + */ + function addExemptWallet(address _wallet) public withPerm(ADMIN) { + require(_wallet != address(0), "Wallet address cannot be a zero address"); + exemptWallets[_wallet] = true; + emit ExemptWalletAdded(_wallet); + } + + /** + * @notice remove an exempt wallet + * @param _wallet exempt wallet address + */ + function removeExemptWallet(address _wallet) public withPerm(ADMIN) { + require(_wallet != address(0), "Wallet address cannot be a zero address"); + exemptWallets[_wallet] = false; + emit ExemptWalletRemoved(_wallet); + } + + /** + * @notice adds an array of exempt wallet + * @param _wallets array of exempt wallet addresses + */ + function addExemptWalletMulti(address[] _wallets) public withPerm(ADMIN) { + require(_wallets.length > 0, "Wallets cannot be empty"); + for (uint256 i = 0; i < _wallets.length; i++) { + addExemptWallet(_wallets[i]); + } + } + + /** + * @notice removes an array of exempt wallet + * @param _wallets array of exempt wallet addresses + */ + function removeExemptWalletMulti(address[] _wallets) public withPerm(ADMIN) { + require(_wallets.length > 0, "Wallets cannot be empty"); + for (uint256 i = 0; i < _wallets.length; i++) { + removeExemptWallet(_wallets[i]); + } + } + + /** + * @notice set transfer limit per wallet + * @param _wallet wallet address + * @param _transferLimit transfer limit for the wallet in tokens + * @dev the manager has to be configured to use limits in tokens + */ + function setTransferLimitInTokens(address _wallet, uint _transferLimit) public withPerm(ADMIN) { + require(_transferLimit > 0, "Transfer limit has to be greater than 0"); + require(!isTransferLimitInPercentage, "Transfer limit not in token amount"); + specialTransferLimitsInTokens[_wallet] = _transferLimit; + emit TransferLimitInTokensSet(_wallet, _transferLimit); + } + + /** + * @notice set transfer limit for a wallet + * @param _wallet wallet address + * @param _transferLimitInPercentage transfer limit for the wallet in percentage. + * Multiply the percentage by 10^16. Eg 22% will be 22*10^16 + * @dev The manager has to be configured to use percentages + */ + function setTransferLimitInPercentage(address _wallet, uint _transferLimitInPercentage) public withPerm(ADMIN) { + require(isTransferLimitInPercentage, "Transfer limit not in percentage"); + require(_transferLimitInPercentage > 0 && _transferLimitInPercentage <= 100 * 10 ** 16, "Transfer limit not in required range"); + specialTransferLimitsInPercentages[_wallet] = _transferLimitInPercentage; + emit TransferLimitInPercentageSet(_wallet, _transferLimitInPercentage); + } + + + /** + * @notice removes transfer limit set in percentage for a wallet + * @param _wallet wallet address + */ + function removeTransferLimitInPercentage(address _wallet) public withPerm(ADMIN) { + require(specialTransferLimitsInPercentages[_wallet] > 0 , "Wallet Address does not have a transfer limit"); + specialTransferLimitsInPercentages[_wallet] = 0; + emit TransferLimitInPercentageRemoved(_wallet); + } + + /** + * @notice removes transfer limit set in tokens for a wallet + * @param _wallet wallet address + */ + function removeTransferLimitInTokens(address _wallet) public withPerm(ADMIN) { + require(specialTransferLimitsInTokens[_wallet] > 0 , "Wallet Address does not have a transfer limit"); + specialTransferLimitsInTokens[_wallet] = 0; + emit TransferLimitInTokensRemoved(_wallet); + } + + /** + * @notice sets transfer limits for an array of wallet + * @param _wallets array of wallet addresses + * @param _transferLimits array of transfer limits for each wallet in tokens + * @dev The manager has to be configured to use tokens as limit + */ + function setTransferLimitInTokensMulti(address[] _wallets, uint[] _transferLimits) public withPerm(ADMIN) { + require(_wallets.length > 0, "Wallets cannot be empty"); + require(_wallets.length == _transferLimits.length); + for (uint256 i=0; i < _wallets.length; i++ ) { + setTransferLimitInTokens(_wallets[i], _transferLimits[i]); + } + } + + /** + * @notice sets transfer limits for an array of wallet + * @param _wallets array of wallet addresses + * @param _transferLimitsInPercentage array of transfer limits for each wallet in percentages + * The percentage has to be multipled by 10 ** 16. Eg: 20% would be 20 * 10 ** 16 + * @dev The manager has to be configured to use percentage as limit + */ + function setTransferLimitInPercentageMulti(address[] _wallets, uint[] _transferLimitsInPercentage) public withPerm(ADMIN) { + require(_wallets.length > 0, "Wallets cannot be empty"); + require(_wallets.length == _transferLimitsInPercentage.length); + for (uint256 i=0; i < _wallets.length; i++) { + setTransferLimitInPercentage(_wallets[i], _transferLimitsInPercentage[i]); + } + } + + /** + * @notice removes transfer limits set in tokens for an array of wallet + * @param _wallets array of wallet addresses + */ + function removeTransferLimitInTokensMulti(address[] _wallets) public withPerm(ADMIN) { + require(_wallets.length > 0, "Wallets cannot be empty"); + for (uint i = 0; i < _wallets.length; i++) { + removeTransferLimitInTokens(_wallets[i]); + } + } + + /** + * @notice removes transfer limits set in percentage for an array of wallet + * @param _wallets array of wallet addresses + */ + function removeTransferLimitInPercentageMulti(address[] _wallets) public withPerm(ADMIN) { + require(_wallets.length > 0, "Wallets cannot be empty"); + for (uint i = 0; i < _wallets.length; i++) { + removeTransferLimitInPercentage(_wallets[i]); + } + } + + /** + * @notice This function returns the signature of configure function + */ + function getInitFunction() public pure returns (bytes4) { + return bytes4(keccak256("configure(bool,uint256)")); + } + + /** + * @notice Return the permissions flag that are associated with SingleTradeVolumeRestrictionManager + */ + function getPermissions() public view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](1); + allPermissions[0] = ADMIN; + return allPermissions; + } +} diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol new file mode 100644 index 000000000..4233d0788 --- /dev/null +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol @@ -0,0 +1,114 @@ +pragma solidity ^0.4.24; + +import "./../ModuleFactory.sol"; +import "./SingleTradeVolumeRestrictionManager.sol"; +import "../../libraries/Util.sol"; +/** + * @title Factory for deploying SingleTradeVolumeRestrictionManager + */ +contract SingleTradeVolumeRestrictionManagerFactory is ModuleFactory { + + + /** + * @notice Constructor + * @param _polyAddress Address of the polytoken + * @param _setupCost Setup cost of the module + * @param _usageCost Usage cost of the module + * @param _subscriptionCost Subscription cost of the module + */ + constructor(address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public + ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + { + version = "1.0.0"; + name = "SingleTradeVolumeRestriction"; + title = "Single Trade Volume Restriction Manager"; + description = "Imposes volume restriction on a single trade"; + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + } + + /** + * @notice used to launch the Module with the help of factory + * @return address Contract address of the Module + */ + function deploy(bytes _data) external returns(address) { + if (setupCost > 0) + require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); + SingleTradeVolumeRestrictionManager singleTradeVolumeRestrictionManager = new SingleTradeVolumeRestrictionManager(msg.sender, address(polyToken)); + + require(Util.getSig(_data) == singleTradeVolumeRestrictionManager.getInitFunction(), "Provided data is not valid"); + require(address(singleTradeVolumeRestrictionManager).call(_data), "Un-successfull call"); + emit GenerateModuleFromFactory(address(singleTradeVolumeRestrictionManager), getName(), address(this), msg.sender, setupCost, now); + return address(singleTradeVolumeRestrictionManager); + } + + /** + * @notice Get the types of the Module factory + * @return uint8[] + */ + function getTypes() external view returns(uint8[]) { + uint8[] memory res = new uint8[](1); + res[0] = 2; + return res; + } + + /** + * @notice Get the name of the Module + * @return bytes32 + */ + function getName() public view returns(bytes32) { + return name; + } + + /** + * @notice Get the description of the Module + * @return string + */ + function getDescription() external view returns(string) { + return description; + } + + /** + * @notice Get the title of the Module + * @return string + */ + function getTitle() external view returns(string) { + return title; + } + + /** + * @notice Get the Instructions that help to use the module + * @return string + */ + function getInstructions() external view returns(string) { + return "Allows an issuer to impose volume restriction on a single trade. Init function takes two parameters. First parameter is a bool indicating if restriction is in percentage. The second parameter is the value in percentage or amount of tokens"; + } + + /** + * @notice Get the version of the Module + * @return string + */ + function getVersion() external view returns(string) { + return version; + } + + /** + * @notice Get the setup cost of the module + * return uint256 + */ + function getSetupCost() external view returns (uint256) { + return setupCost; + } + /** + * @notice Get the tags related to the module factory + * @return bytes32[] + */ + function getTags() external view returns(bytes32[]) { + bytes32[] memory availableTags = new bytes32[](3); + availableTags[0] = "Single Trade"; + availableTags[1] = "Transfer"; + availableTags[2] = "Volume"; + return availableTags; + } + +} diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index a3af87a97..95b56bc68 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -86,9 +86,12 @@ contract('PercentageTransferManager', accounts => { inputs: [{ type: 'uint256', name: '_maxHolderPercentage' + },{ + type: 'bool', + name: '_allowPrimaryIssuance' } ] - }, [holderPercentage]); + }, [holderPercentage, false]); const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; const MRProxyParameters = ['address', 'address']; @@ -330,7 +333,7 @@ contract('PercentageTransferManager', accounts => { ); }); - it("Should successfully attach the PercentageTransferManagerr factory with the security token", async () => { + it("Should successfully attach the PercentageTransferManager factory with the security token - failed payment", async () => { let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); try { @@ -414,6 +417,25 @@ contract('PercentageTransferManager', accounts => { await I_PercentageTransferManager.unpause({from: token_owner}); }) + it("Should not be able to mint token amount over limit", async() => { + let errorThrown = false; + try { + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('100', 'ether'), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> Too high minting`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Allow unlimited primary issuance and remint", async() => { + let snapId = await takeSnapshot(); + await I_PercentageTransferManager.setAllowPrimaryIssuance(true, { from: token_owner }); + await I_SecurityToken.mint(account_investor3, web3.utils.toWei('100', 'ether'), { from: token_owner }); + await revertToSnapshot(snapId); + }); + it("Should not be able to transfer between existing token holders over limit", async() => { let errorThrown = false; try { @@ -450,7 +472,7 @@ contract('PercentageTransferManager', accounts => { it("Should get the permission", async() => { let perm = await I_PercentageTransferManager.getPermissions.call(); - assert.equal(perm.length, 1); + assert.equal(perm.length, 2); }); }); diff --git a/test/x_single_trade_volume_restriction.js b/test/x_single_trade_volume_restriction.js new file mode 100644 index 000000000..ef60a5639 --- /dev/null +++ b/test/x_single_trade_volume_restriction.js @@ -0,0 +1,1162 @@ +import latestTime from './helpers/latestTime'; +import { + duration, + ensureException, + promisifyLogWatch, + latestBlock +} from './helpers/utils'; +import takeSnapshot, { + increaseTime, + revertToSnapshot +} from './helpers/time'; +import { + encodeProxyCall +} from './helpers/encodeCall'; + +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +const SecurityToken = artifacts.require('./SecurityToken.sol'); +const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); +const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); +const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const SingleTradeVolumeRestrictionManagerFactory = artifacts.require('./SingleTradeVolumeRestrictionManagerFactory.sol'); +const SingleTradeVolumeRestrictionManager = artifacts.require('./SingleTradeVolumeRestrictionManager'); +const CountTransferManagerFactory = artifacts.require('./CountTransferManagerFactory.sol'); +const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); +const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); + +const Web3 = require('web3'); +const BigNumber = require('bignumber.js'); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract('SingleTradeVolumeRestrictionManager', accounts => { + + + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_investor5; + let zero_address = '0x0000000000000000000000000000000000000000'; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_SecurityTokenRegistryProxy + let I_GeneralPermissionManagerFactory; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_SingleTradeVolumeRestrictionManagerFactory; + let I_SingleTradeVolumeRestrictionManager; + let P_SingleTradeVolumeRestrictionManagerFactory; + let P_SingleTradeVolumeRestrictionManager; + let I_SingleTradeVolumeRestrictionPercentageManager; + let I_ModuleRegistry; + let I_MRProxied; + let I_ModuleRegistryProxy; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_STRProxied; + let I_STFactory; + let I_SecurityToken; + let I_PolyToken; + let I_PolymathRegistry; + + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + // SecurityToken Details + const swarmHash = "dagwrgwgvwergwrvwrg"; + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + before(async () => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_investor5 = accounts[5]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({ + from: account_polymath + }); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, { + from: account_polymath + }); + + // STEP 2: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({ + from: account_polymath + }); + // + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ + from: account_polymath + }); + + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { + from: account_polymath + }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + + // + // + // // STEP 2: Deploy the GeneralTransferManagerFactory + // + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 3: Deploy the GeneralDelegateManagerFactoryFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 4: Deploy the SingleTradeVolumeRestrictionManagerFactory + I_SingleTradeVolumeRestrictionManagerFactory = await SingleTradeVolumeRestrictionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { + from: account_polymath + }); + + assert.notEqual( + I_SingleTradeVolumeRestrictionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SingleTradeVolumeRestrictionManagerFactory contract was not deployed" + ); + + + P_SingleTradeVolumeRestrictionManagerFactory = await SingleTradeVolumeRestrictionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, { + from: account_polymath + }); + assert.notEqual( + P_SingleTradeVolumeRestrictionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SingleTradeVolumeRestrictionManagerFactory contract was not deployed" + ); + // + // + // // Step 6: Deploy the STFactory contract + // + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { + from: account_polymath + }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 7: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ + from: account_polymath + }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 8: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ + from: account_polymath + }); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + // + // // Step 9: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { + from: account_polymath + }) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { + from: account_polymath + }); + await I_MRProxied.updateFromRegistry({ + from: account_polymath + }); + + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { + from: account_polymath + }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { + from: account_polymath + }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { + from: account_polymath + }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { + from: account_polymath + }); + + // (C) : Register the SingleTradeVolumeRestrictionManagerFactory + await I_MRProxied.registerModule(I_SingleTradeVolumeRestrictionManagerFactory.address, { + from: account_polymath + }); + await I_MRProxied.verifyModule(I_SingleTradeVolumeRestrictionManagerFactory.address, true, { + from: account_polymath + }); + + // (C) : Register the Paid SingleTradeVolumeRestrictionManagerFactory + await I_MRProxied.registerModule(P_SingleTradeVolumeRestrictionManagerFactory.address, { + from: account_polymath + }); + await I_MRProxied.verifyModule(P_SingleTradeVolumeRestrictionManagerFactory.address, true, { + from: account_polymath + }); + }) + + describe("Generate the SecurityToken", async () => { + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { + from: token_owner + }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { + from: token_owner + }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { + from: token_owner + }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { + from: token_owner + }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ + from: _blockNo + }), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._types[0].toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + }); + // + describe("Buy tokens using whitelist & manual approvals", async () => { + + it("Should Buy the tokens", async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, { + from: account_issuer + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor1.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Jump time + await increaseTime(5000); + + // Mint some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('100', 'ether'), { + from: token_owner + }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor1)).toNumber(), + web3.utils.toWei('100', 'ether') + ); + }); + + it("Should Buy some more tokens", async () => { + // Add the Investor in to the whitelist + + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, { + from: account_issuer + }); + + assert.equal(tx.logs[0].args._investor.toLowerCase(), account_investor2.toLowerCase(), "Failed in adding the investor in whitelist"); + + // Mint some tokens + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('1', 'ether'), { + from: token_owner + }); + + assert.equal( + (await I_SecurityToken.balanceOf(account_investor2)).toNumber(), + web3.utils.toWei('1', 'ether') + ); + }); + // + it("Fails to attach the SingleTradeVolumeRestrictionManager with the security token due to fees not paid", async () => { + let managerArgs = web3.eth.abi.encodeFunctionCall({ + name: 'configure', + type: 'function', + inputs: [{ + type: 'bool', + name: '_isTransferLimitInPercentage' + }, + { + type: 'uint256', + name: '_globalTransferLimitInPercentageOrToken' + } + ] + }, [true, 90]) + let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + try { + const tx = await I_SecurityToken.addModule(P_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }); + } catch (error) { + console.log(` tx -> failed because Token is not paid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + + + it("Should successfully attach the Paid SingleTradeVolumeRestrictionManager with the security token", async () => { + let managerArgs = web3.eth.abi.encodeFunctionCall({ + name: 'configure', + type: 'function', + inputs: [{ + type: 'bool', + name: '_isTransferLimitInPercentage' + }, + { + type: 'uint256', + name: '_globalTransferLimitInPercentageOrToken' + } + ] + }, [false, 90]); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { + from: token_owner + }); + let tx = await I_SecurityToken.addModule(P_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }); + assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "SingleTradeVolumeRestrictionManager did not get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), + "SingleTradeVolumeRestriction", + "SingleTradeVolumeRestrictionManagerFactory module was not added" + ); + P_SingleTradeVolumeRestrictionManager = SingleTradeVolumeRestrictionManager.at(tx.logs[3].args._module); + }); + + it("Should successfully attach the SingleTradeVolumeRestrictionManager with the security token", async () => { + let managerArgs = web3.eth.abi.encodeFunctionCall({ + name: 'configure', + type: 'function', + inputs: [{ + type: 'bool', + name: '_isTransferLimitInPercentage' + }, + { + type: 'uint256', + name: '_globalTransferLimitInPercentageOrToken' + } + ] + }, [false, 7 * 10 ** 16]) + const tx = await I_SecurityToken.addModule(I_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, 0, 0, { + from: token_owner + }); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "SingleTradeVolumeRestriction", + "SingleTradeVolumeRestriction module was not added" + ); + I_SingleTradeVolumeRestrictionManager = SingleTradeVolumeRestrictionManager.at(tx.logs[2].args._module); + }); + + it("Should successfully attach the SingleTradeVolumeRestrictionManager (Percentage) with the security token", async () => { + let managerArgs = web3.eth.abi.encodeFunctionCall({ + name: 'configure', + type: 'function', + inputs: [{ + type: 'bool', + name: '_isTransferLimitInPercentage' + }, + { + type: 'uint256', + name: '_globalTransferLimitInPercentageOrToken' + } + ] + }, [true, 90]); + const tx = await I_SecurityToken.addModule(I_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, 0, 0, { + from: token_owner + }); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "SingleTradeVolumeRestriction", + "SingleTradeVolumeRestriction module was not added" + ); + I_SingleTradeVolumeRestrictionPercentageManager = SingleTradeVolumeRestrictionManager.at(tx.logs[2].args._module); + }); + + it('should return get permissions', async () => { + let permissions = await I_SingleTradeVolumeRestrictionPercentageManager.getPermissions(); + assert.equal(permissions.length, 1, "Invalid Permissions"); + assert.equal( + web3.utils.toAscii(permissions[0]).replace(/\u0000/g, ''), + "ADMIN", + 'Wrong permissions' + ); + }); + + it('add exempt wallet', async () => { + let errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.addExemptWallet(accounts[5]); + } catch (e) { + errorThrown = true; + } + assert.ok(errorThrown, "Non Admins cannot add exempt wallets"); + + errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.addExemptWallet(zero_address, { + from: token_owner + }); + } catch (e) { + ensureException(e); + errorThrown = true; + } + + assert.ok(errorThrown, "Exempt wallet cannot be zero"); + + let tx = await I_SingleTradeVolumeRestrictionManager.addExemptWallet(accounts[5], { + from: token_owner + }); + assert.equal(tx.logs[0].args._wallet, accounts[5], "Wrong wallet added as exempt"); + }); + + it('should remove an exempt wallet', async () => { + let errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.removeExemptWallet(accounts[5]); + } catch (e) { + errorThrown = true; + } + assert.ok(errorThrown, "Non Admins cannot add exempt wallets"); + + errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.removeExemptWallet(zero_address, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + + assert.ok(errorThrown, "Zero address cannot be added to exempt wallet"); + + let tx = await I_SingleTradeVolumeRestrictionManager.removeExemptWallet(accounts[5], { + from: token_owner + }); + assert.equal(tx.logs[0].args._wallet, accounts[5], "Wrong wallet removed from exempt"); + }); + + it('should set transfer limit for a wallet', async () => { + let errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 100); + } catch (e) { + errorThrown = true; + } + assert.ok(errorThrown, "Non Admins cannot set transfer limits"); + + errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 0, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Transfer limit cannot be set to 0") + errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInPercentage(accounts[4], 10, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Transfer limit cannot be set in percentage") + let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 100, { + from: token_owner + }); + assert.equal(tx.logs[0].args._wallet, accounts[4]); + assert.equal(tx.logs[0].args._amount, 100); + + errorThrown = false; + try { + tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 0, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + errorThrown = false + try { + tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 101 * 10 ** 16, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Transfer limit can not be set to more 0") + errorThrown = false; + try { + tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInTokens(accounts[4], 1, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + + assert.ok(errorThrown, "Transfer limit in tokens can not be set for a manager that has transfer limit set as percentage") + tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 50, { + from: token_owner + }); + assert.equal(tx.logs[0].args._wallet, accounts[4], "Wrong wallet added to transfer limits"); + assert.equal(tx.logs[0].args._percentage, 50, "Wrong percentage set"); + }); + + it('should remove transfer limit for wallet', async () => { + let errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[4]); + } catch (e) { + errorThrown = true; + } + assert.ok(errorThrown, "Non Admins cannot set/remove transfer limits"); + + errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[0], { + from: token_owner + }); + } catch (e) { + errorThrown = true; + } + assert.ok(errorThrown, "Non Admins cannot set/remove transfer limits"); + + let tx = await I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[4], { + from: token_owner + }); + assert.equal(tx.logs[0].args._wallet, accounts[4], "Wrong wallet removed"); + }); + + it("Should pause the tranfers at Manager level", async () => { + let tx = await I_SingleTradeVolumeRestrictionManager.pause({ + from: token_owner + }); + }); + + it('should be able to set a global transfer limit', async () => { + let errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(100 * 10 ** 18); + } catch (e) { + errorThrown = true; + } + assert.ok(errorThrown, "only owner is allowed"); + + errorThrown = false; + + try { + let tx = await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInPercentage(100 * 10 ** 18, { + from: token_owner + }); + } catch (e) { + ensureException(e); + errorThrown = true; + } + assert.ok(errorThrown, "Cannot change global limit in percentage when set to tokens"); + + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(0, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Global limit cannot be set to 0"); + let tx = await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(10, { + from: token_owner + }); + assert.equal(tx.logs[0].args._amount, 10, "Global Limit not set"); + + errorThrown = false; + + try { + let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(89); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Global limit can be set by non-admins"); + + errorThrown = false; + + try { + let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(89, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "cannot change global limit in tokens if transfer limit is set to percentage"); + + errorThrown = false; + try { + let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(0, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Cannot set global limit in tokens to 0"); + + tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInPercentage(40, { + from: token_owner + }); + assert.equal(tx.logs[0].args._percentage, 40, "Global Limit not set"); + + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInPercentage(101 * 10 ** 16, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Global limit cannot be set to more than 100"); + + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInPercentage(10, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Global limit in percentage cannot be set when limit is in tokens"); + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(10, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Global limit in tokens cannot be set when limit is in percentage"); + }); + + it('should perform batch updates', async () => { + let wallets = [accounts[0], accounts[1], accounts[2]]; + let tokenLimits = [1, 2, 3]; + let percentageLimits = [5, 6, 7]; + + let errorThrown = false; + try { + await P_SingleTradeVolumeRestrictionManager.addExemptWalletMulti([], { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Exempt wallet multi cannot be empty wallet"); + + // add exempt wallet multi + let tx = await P_SingleTradeVolumeRestrictionManager.addExemptWalletMulti(wallets, { + from: token_owner + }); + let logs = tx.logs.filter(log => log.event === 'ExemptWalletAdded'); + assert.equal(logs.length, wallets.length, "Batch Exempt wallets not added"); + for (let i = 0; i < logs.length; i++) { + assert.equal(logs[i].args._wallet, wallets[i], "Wallet not added as exempt wallet"); + } + + errorThrown = false; + try { + await P_SingleTradeVolumeRestrictionManager.removeExemptWalletMulti([], { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Exempt wallet multi cannot be empty wallet"); + + // remove exempt wallet multi + tx = await P_SingleTradeVolumeRestrictionManager.removeExemptWalletMulti(wallets, { + from: token_owner + }) + logs = tx.logs.filter(log => log.event === 'ExemptWalletRemoved'); + assert.equal(logs.length, wallets.length, "Batch Exempt wallets not removed"); + + for (let i = 0; i < logs.length; i++) { + assert.equal(logs[i].args._wallet, wallets[i], "Wallet not added as exempt wallet"); + } + + errorThrown = false; + try { + tx = await P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti([], tokenLimits, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "wallets cannot be empty"); + + errorThrown = false; + try { + tx = await P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti([accounts[0]], tokenLimits, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "wallet array length dont match"); + + tx = await P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti(wallets, tokenLimits, { + from: token_owner + }); + logs = tx.logs.filter(log => log.event == 'TransferLimitInTokensSet'); + assert.equal(wallets.length, logs.length, "Transfer limit not set"); + for (let i = 0; i < wallets.length; i++) { + assert.equal(logs[i].args._wallet, wallets[i], "transfer limit not set for wallet"); + assert.equal(logs[i].args._amount.toNumber(), tokenLimits[i]); + } + errorThrown = false + try { + await P_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokensMulti([], { + from: token_owner + }); + } catch (e) { + ensureException(e); + errorThrown = true; + } + assert.ok(errorThrown, "Wallets cannot be empty"); + tx = await P_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokensMulti(wallets, { + from: token_owner + }); + logs = tx.logs.filter(log => log.event === 'TransferLimitInTokensRemoved'); + assert.equal(logs.length, wallets.length, "Transfer limit not removed"); + for (let i = 0; i < wallets.length; i++) { + assert.equal(logs[i].args._wallet, wallets[i], "transfer limit not removed for wallet"); + } + + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti([], percentageLimits, { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "wallets cannot be empty"); + + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti(wallets, [], { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "wallets and amounts dont match be empty"); + tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti(wallets, percentageLimits, { + from: token_owner + }); + logs = tx.logs.filter(log => log.event == 'TransferLimitInPercentageSet'); + assert.equal(logs.length, wallets.length, "transfer limits not set for wallets"); + + for (let i = 0; i < wallets.length; i++) { + assert.equal(logs[i].args._wallet, wallets[i], "Transfer limit not set for wallet"); + assert.equal(logs[i].args._percentage.toNumber(), percentageLimits[i]); + } + + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentageMulti([], { + from: token_owner + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Wallets cannot be empty"); + + tx = await I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentageMulti(wallets, { + from: token_owner + }); + logs = tx.logs.filter(log => log.event == 'TransferLimitInPercentageRemoved'); + assert.equal(logs.length, wallets.length, "transfer limits not set for wallets"); + + for (let i = 0; i < wallets.length; i++) { + assert.equal(logs[i].args._wallet, wallets[i], "Transfer limit not set for wallet"); + } + + errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentage(wallets[0], { + from: token_owner + }); + } catch (e) { + ensureException(e) + errorThrown = true; + } + assert.ok(errorThrown, "Wallet should not be removed"); + }) + + it('should be able to transfer tokens SingleTradeVolumeRestriction', async () => { + await I_SingleTradeVolumeRestrictionManager.unpause({ + from: token_owner + }) + await I_SingleTradeVolumeRestrictionPercentageManager.pause({ + from: token_owner + }) + await P_SingleTradeVolumeRestrictionManager.pause({ + from: token_owner + }); + + await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, { + from: account_issuer + } + ); + + await I_GeneralTransferManager.modifyWhitelist( + account_investor4, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, { + from: account_issuer + } + ); + + await I_GeneralTransferManager.modifyWhitelist( + account_investor5, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, { + from: account_issuer + } + ); + + + //setting a max of 5 tokens + await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(web3.utils.toWei('5', 'ether'), { + from: token_owner + }) + + let errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('6', 'ether'), { + from: account_investor1 + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Transfer should have not happened"); + await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('4', 'ether'), { + from: account_investor1 + }); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('4', 'ether')); + + // exempt wallet + await I_SingleTradeVolumeRestrictionManager.addExemptWallet(account_investor1, { + from: token_owner + }); + await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('7', 'ether'), { + from: account_investor1 + }); + assert.equal((await I_SecurityToken.balanceOf(account_investor5)).toNumber(), web3.utils.toWei('7', 'ether')); + + //special limits wallet + await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(account_investor5, web3.utils.toWei('5', 'ether'), { + from: token_owner + }); + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('7', 'ether'), { + from: account_investor5 + }); + } catch (e) { + errorThrown = true; + ensureException(e); + } + assert.ok(errorThrown, "Transfer should have not happened"); + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('4', 'ether'), { + from: account_investor5 + }) + assert.equal((await I_SecurityToken.balanceOf(account_investor4)).toNumber(), web3.utils.toWei('4', 'ether')) + }) + + it('should be able to transfer tokens (percentage transfer limit)', async () => { + await I_SingleTradeVolumeRestrictionManager.pause({ + from: token_owner + }); + let balance = (await I_SecurityToken.balanceOf(account_investor2)).toNumber(); + await I_SecurityToken.transfer(account_investor1, balance, { + from: account_investor2 + }); + + + balance = (await I_SecurityToken.balanceOf(account_investor3)).toNumber(); + + await I_SecurityToken.transfer(account_investor1, balance, { + from: account_investor3 + }); + + + balance = (await I_SecurityToken.balanceOf(account_investor4)).toNumber(); + await I_SecurityToken.transfer(account_investor1, balance, { + from: account_investor4 + }); + + balance = (await I_SecurityToken.balanceOf(account_investor5)).toNumber(); + await I_SecurityToken.transfer(account_investor1, balance, { + from: account_investor5 + }); + + await I_SingleTradeVolumeRestrictionPercentageManager.unpause({ + from: token_owner + }); + // // + await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInPercentage(49 * 10 ** 16, { + from: token_owner + }); + + let errorThrown = false; + try { + // more than the limit + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('90', 'ether'), { + from: account_investor1 + }); + } catch (e) { + ensureException(e); + errorThrown = true; + } + assert.ok(errorThrown, "Transfer above limit happened"); + + + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('20', 'ether'), { + from: account_investor1 + }); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei('20', 'ether')) + + await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(account_investor1, 5 * 10 ** 16, { + from: token_owner + }); + errorThrown = false; + try { + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('35', 'ether'), { + from: account_investor1 + }); + } catch (e) { + ensureException(e); + errorThrown = true; + } + assert.ok(errorThrown, "transfer happened above limit"); + + await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('1', 'ether'), { + from: account_investor1 + }); + assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei('1', 'ether')); + }); + + it('should change transfer limits to tokens', async () => { + let errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionPercentageManager.changeTransferLimitToPercentage(1, { + from: token_owner + }); + } catch (e) { + + ensureException(e); + errorThrown = true; + } + assert.equal(errorThrown, true, "Should not change to percentage again"); + + + let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeTransferLimitToTokens(1, { + from: token_owner + }); + assert.equal(await I_SingleTradeVolumeRestrictionPercentageManager.isTransferLimitInPercentage(), false, "Error Changing"); + assert.equal(tx.logs[0].args._amount.toNumber(), 1, "Transfer limit not changed"); + }) + + it('should change transfer limits to percentage', async () => { + let errorThrown = false; + try { + await I_SingleTradeVolumeRestrictionManager.changeTransferLimitToTokens(1, { + from: token_owner + }); + } catch (e) { + ensureException(e); + errorThrown = true; + } + assert.equal(errorThrown, true, "Should not change to tokens again"); + + let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeTransferLimitToPercentage(1, { + from: token_owner + }); + assert.ok(await I_SingleTradeVolumeRestrictionPercentageManager.isTransferLimitInPercentage(), "Error Changing"); + assert.equal(tx.logs[0].args._percentage.toNumber(), 1, "Transfer limit not changed"); + }) + + + + }); + + describe("SingleTradeVolumeRestrictionManager Factory test cases", async () => { + + it("Should get the exact details of the factory", async () => { + assert.equal(await I_SingleTradeVolumeRestrictionManagerFactory.setupCost.call(), 0); + assert.equal((await I_SingleTradeVolumeRestrictionManagerFactory.getTypes.call())[0], 2); + let name = web3.utils.toUtf8(await I_SingleTradeVolumeRestrictionManagerFactory.getName.call()); + assert.equal(name, "SingleTradeVolumeRestriction", "Wrong Module added"); + let desc = await I_SingleTradeVolumeRestrictionManagerFactory.getDescription.call(); + assert.equal(desc, "Imposes volume restriction on a single trade", "Wrong Module added"); + let title = await I_SingleTradeVolumeRestrictionManagerFactory.getTitle.call(); + assert.equal(title, "Single Trade Volume Restriction Manager", "Wrong Module added"); + let inst = await I_SingleTradeVolumeRestrictionManagerFactory.getInstructions.call(); + assert.equal(inst, "Allows an issuer to impose volume restriction on a single trade. Init function takes two parameters. First parameter is a bool indicating if restriction is in percentage. The second parameter is the value in percentage or amount of tokens", "Wrong Module added"); + let version = await I_SingleTradeVolumeRestrictionManagerFactory.getVersion.call(); + assert.equal(version, "1.0.0", "Version not correct"); + }); + + it("Should get the tags of the factory", async () => { + let tags = await I_SingleTradeVolumeRestrictionManagerFactory.getTags.call(); + assert.equal(web3.utils.toUtf8(tags[0]), "Single Trade"); + assert.equal(web3.utils.toUtf8(tags[1]), "Transfer"); + assert.equal(web3.utils.toUtf8(tags[2]), "Volume"); + }); + + + }); +}); From 3851971e1f9369da8e5a6978c2dd323cdc0fc865 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Fri, 5 Oct 2018 12:11:24 +0100 Subject: [PATCH 079/142] Fix test cases --- test/x_single_trade_volume_restriction.js | 24 +++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/x_single_trade_volume_restriction.js b/test/x_single_trade_volume_restriction.js index ef60a5639..64813eed1 100644 --- a/test/x_single_trade_volume_restriction.js +++ b/test/x_single_trade_volume_restriction.js @@ -385,9 +385,13 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { { type: 'uint256', name: '_globalTransferLimitInPercentageOrToken' + }, + { + type: 'bool', + name: '_allowPrimaryIssuance' } ] - }, [true, 90]) + }, [true, 90, false]) let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); try { @@ -415,9 +419,13 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { { type: 'uint256', name: '_globalTransferLimitInPercentageOrToken' + }, + { + type: 'bool', + name: '_allowPrimaryIssuance' } ] - }, [false, 90]); + }, [false, 90, false]); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); @@ -445,9 +453,13 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { { type: 'uint256', name: '_globalTransferLimitInPercentageOrToken' + }, + { + type: 'bool', + name: '_allowPrimaryIssuance' } ] - }, [false, 7 * 10 ** 16]) + }, [false, 7 * 10 ** 16, false]) const tx = await I_SecurityToken.addModule(I_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, 0, 0, { from: token_owner }); @@ -472,9 +484,13 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { { type: 'uint256', name: '_globalTransferLimitInPercentageOrToken' + }, + { + type: 'bool', + name: '_allowPrimaryIssuance' } ] - }, [true, 90]); + }, [true, 90, false]); const tx = await I_SecurityToken.addModule(I_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, 0, 0, { from: token_owner }); From aa274eb216dac281ec460a27e9c9a6b9616e3ab3 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 16:42:07 +0530 Subject: [PATCH 080/142] closing the coverage --- scripts/coverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/coverage.sh b/scripts/coverage.sh index e42ed6a84..c383e2022 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -2,4 +2,4 @@ rm -rf flat -TRAVIS_PULL_REQUEST=true scripts/test.sh \ No newline at end of file +TRAVIS_PULL_REQUEST=false scripts/test.sh \ No newline at end of file From 3affcd02211f92f60f755e60488fb1d53f460e18 Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Fri, 5 Oct 2018 12:14:17 +0100 Subject: [PATCH 081/142] Another fix --- .../TransferManager/SingleTradeVolumeRestrictionManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol index c66ca8e26..dc9f64485 100644 --- a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol @@ -299,7 +299,7 @@ contract SingleTradeVolumeRestrictionManager is ITransferManager { * @notice This function returns the signature of configure function */ function getInitFunction() public pure returns (bytes4) { - return bytes4(keccak256("configure(bool,uint256)")); + return bytes4(keccak256("configure(bool,uint256,bool)")); } /** From 186b9fd469f61b75a2d8872bf4680767c0815e8c Mon Sep 17 00:00:00 2001 From: Adam Dossa Date: Fri, 5 Oct 2018 12:16:11 +0100 Subject: [PATCH 082/142] Update change log --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca2181f6b..2827a58a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file. [__1.5.0__](https://www.npmjs.com/package/polymath-core?activeTab=readme) __15-08-18__ ## Added +* Added `SingleTradeVolumeRestrictionManager` module +* Added flag in `PercentageTransferManager` to allow ignoring of issuance transfers +* Added `transferWithData`, `transferFromWithData`, `mintWithData`, `burnWithData` to allow passing of a `bytes _data` for off-chain validation +* Added ability for modules to have multiple types * Added `name` field to dividends struct in DividendCheckpoint. #295 * Added `getTagsByType`, `getTagsByTypeAndToken`, `getModulesByType`, `getModulesByTypeAndToken` to MR * Added `getTokensByOwner` to STR From 5976c9a4f0ceecf2192461a3c3fcface4c7102aa Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Fri, 5 Oct 2018 13:29:18 +0200 Subject: [PATCH 083/142] copy files over based on dev 1.5.0 --- .eslintrc.js | 10 + .gitignore | 3 +- .../Checkpoint/WeightedVoteCheckpoint.sol | 132 +++++ .../WeightedVoteCheckpointFactory.sol | 76 +++ test/weighted_vote.js | 450 ++++++++++++++++++ 5 files changed, 670 insertions(+), 1 deletion(-) create mode 100644 contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol create mode 100644 contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol create mode 100644 test/weighted_vote.js diff --git a/.eslintrc.js b/.eslintrc.js index b173360a3..463539deb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,4 +6,14 @@ module.exports = { "assert": false, "web3": false }, + + "rules": { + "indent": 0, + "camelcase": 0, + "no-unused-vars": 0, + "quotes": 0, + "semi": 0, + "no-undef": 0, + "key-spacing": 0 + } }; diff --git a/.gitignore b/.gitignore index 40890224b..fb4573022 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ coverage.json bridge.log scTopics coverageEnv -/flat \ No newline at end of file +/flat +.eslintrc.js \ No newline at end of file diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol new file mode 100644 index 000000000..0d88f82ca --- /dev/null +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol @@ -0,0 +1,132 @@ +pragma solidity ^0.4.24; + +import "./ICheckpoint.sol"; +import "../Module.sol"; +import "openzeppelin-solidity/contracts/math/SafeMath.sol"; + +/** + * @title Checkpoint module for token weighted vote + * @notice This voting system uses public votes + */ +contract WeightedVoteCheckpoint is ICheckpoint { + using SafeMath for uint256; + + struct Ballot { + uint256 checkpointId; + uint256 totalSupply; + uint256 startTime; + uint256 endTime; + uint256 cumulativeYes; + uint256 cumulativeNo; + uint256 numVotes; + mapping(address => Vote) voteByAddress; + } + + Ballot[] public ballots; + + struct Vote { + uint256 time; + uint256 weight; + bool vote; + } + + event BallotCreated(uint256 _startTime, uint256 _endTime, uint256 _ballotId, uint256 _checkpointId); + event VoteCasted(uint256 _ballotId, uint256 _time, address indexed _investor, uint256 _weight, bool _vote); + + /** + * @notice Constructor + * @param _securityToken Address of the security token + * @param _polyAddress Address of the polytoken + */ + constructor(address _securityToken, address _polyAddress) public IModule(_securityToken, _polyAddress) { + + } + + /** + * @notice Queries the result of a given ballot + * @param _ballotId Id of the target ballot + * @return uint256 cummulativeYes + * @return uint256 cummulativeNo + * @return uint256 totalAbstain + * @return uint256 remainingTime + */ + function getResults(uint256 _ballotId) public view returns (uint256 cummulativeYes, uint256 cummulativeNo, uint256 totalAbstain, uint256 remainingTime) { + uint256 abstain = (ballots[_ballotId].totalSupply.sub(ballots[_ballotId].cumulativeYes)).sub(ballots[_ballotId].cumulativeNo); + uint256 time = (ballots[_ballotId].endTime > now) ? ballots[_ballotId].endTime.sub(now) : 0; + return (ballots[_ballotId].cumulativeYes, ballots[_ballotId].cumulativeNo, abstain, time); + } + + /** + * @notice Allows a token holder to cast their vote on a specific ballot + * @param _vote The vote (true/false) in favor or against the proposal + * @param _ballotId The index of the target ballot + * @return bool success + */ + function castVote(bool _vote, uint256 _ballotId) public returns (bool) { + require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); + require(ballots[_ballotId].voteByAddress[msg.sender].time == 0, "Token holder has already voted."); + uint256 checkpointId = ballots[_ballotId].checkpointId; + uint256 weight = ISecurityToken(securityToken).balanceOfAt(msg.sender,checkpointId); + require(weight > 0, "Token Holder balance is zero."); + ballots[_ballotId].voteByAddress[msg.sender].time = now; + ballots[_ballotId].voteByAddress[msg.sender].weight = weight; + ballots[_ballotId].voteByAddress[msg.sender].vote = _vote; + ballots[_ballotId].numVotes = ballots[_ballotId].numVotes.add(1); + if (_vote == true) { + ballots[_ballotId].cumulativeYes = ballots[_ballotId].cumulativeYes.add(weight); + } else { + ballots[_ballotId].cumulativeNo = ballots[_ballotId].cumulativeNo.add(weight); + } + emit VoteCasted(_ballotId, now, msg.sender, weight, _vote); + return true; + } + + /** + * @notice Allows the token issuer to create a ballot + * @param _duration The duration of the voting period in seconds + * @return bool success + */ + function createBallot(uint256 _duration) public onlyOwner returns (bool) { + uint256 ballotId = ballots.length; + uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); + uint256 currentSupply = ISecurityToken(securityToken).totalSupply(); + uint256 endTime = now.add(_duration); + ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0)); + emit BallotCreated(now, endTime, ballotId, checkpointId); + return true; + } + + /** + * @notice Allows the token issuer to create a ballot with custom settings + * @param _startTime Start time of the voting period in Unix Epoch time + * @param _endTime End time of the voting period in Unix Epoch time + * @param _checkpointId Index of the checkpoint to use for token balances + * @return bool success + */ + function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner returns (bool) { + require(_endTime >= _startTime); + uint256 ballotId = ballots.length; + uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); + ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0)); + emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); + return true; + } + + /** + * @notice Init function i.e generalise function to maintain the structure of the module contract + * @return bytes4 + */ + function getInitFunction() public returns(bytes4) { + return bytes4(0); + } + + /** + * @notice Return the permissions flag that are associated with STO + * @return bytes32 array + */ + function getPermissions() public view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](0); + return allPermissions; + } + +} diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol new file mode 100644 index 000000000..0531826aa --- /dev/null +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol @@ -0,0 +1,76 @@ +pragma solidity ^0.4.24; + +import "./WeightedVoteCheckpoint.sol"; +import "../../interfaces/IModuleFactory.sol"; + +/** + * @title Factory for deploying WeightedVoteCheckpoint module + */ +contract WeightedVoteCheckpointFactory is IModuleFactory { + + /** + * @notice Constructor + * @param _polyAddress Address of the polytoken + * @param _setupCost Setup cost of the module + * @param _usageCost Usage cost of the module + * @param _subscriptionCost Subscription cost of the module + */ + constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public + IModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + { + + } + + /** + * @notice used to launch the Module with the help of factory + * @return address Contract address of the Module + */ + function deploy(bytes /* _data */) external returns(address) { + if (setupCost > 0) + require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); + return address(new WeightedVoteCheckpoint(msg.sender, address(polyToken))); + } + + * + * @notice Type of the Module factory + + function getType() public view returns(uint8) { + return 4; + } + + /** + * @notice Get the name of the Module + */ + function getName() public view returns(bytes32) { + return "WeightedVoteCheckpoint"; + } + + /** + * @notice Get the description of the Module + */ + function getDescription() public view returns(string) { + return "Create votes for single issue token weighted votes"; + } + + /** + * @notice Get the title of the Module + */ + function getTitle() public view returns(string) { + return "Weighted Vote Checkpoint"; + } + + /** + * @notice Get the Instructions that helped to used the module + */ + function getInstructions() public view returns(string) { + return "Create a vote which allows token holders to vote on an issue with a weight proportional to their balances at the point the vote is created"; + } + + /** + * @notice Get the tags related to the module factory + */ + function getTags() public view returns(bytes32[]) { + bytes32[] memory availableTags = new bytes32[](0); + return availableTags; + } +} diff --git a/test/weighted_vote.js b/test/weighted_vote.js new file mode 100644 index 000000000..f5a0688b3 --- /dev/null +++ b/test/weighted_vote.js @@ -0,0 +1,450 @@ +import latestTime from './helpers/latestTime'; +import { duration, ensureException } from './helpers/utils'; +import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; +import { error } from 'util'; + +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 STVersion = artifacts.require('./STVersionProxy001.sol'); +const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); +const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); +const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const WeightedVoteCheckpointFactory = artifacts.require('./WeightedVoteCheckpointFactory.sol'); +const WeightedVoteCheckpoint = artifacts.require('./WeightedVoteCheckpoint'); +const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); +const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); + +const Web3 = require('web3'); +const BigNumber = require('bignumber.js'); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract('WeightedVoteCheckpoint', accounts => { + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_temp; + + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManagerFactory; + let I_GeneralTransferManager; + let I_WeightedVoteCheckpointFactory; + let I_WeightedVoteCheckpoint; + let I_ExchangeTransferManager; + let I_ModuleRegistry; + let I_TickerRegistry; + let I_SecurityTokenRegistry; + let I_STVersion; + let I_SecurityToken; + let I_PolyToken; + + // SecurityToken Details + const swarmHash = "dagwrgwgvwergwrvwrg"; + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + let snapId; + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + const checkpointKey = 4; + + // Initial fee for ticker registry and security token registry + const initRegFee = 250 * Math.pow(10, 18); + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // STEP 1: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + + assert.notEqual( + I_ModuleRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ModuleRegistry contract was not deployed" + ); + + // STEP 2: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 3: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + // STEP 4: Deploy the WeightedVoteCheckpointFactory + I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + assert.notEqual( + I_WeightedVoteCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "WeightedVoteCheckpointFactory contract was not deployed" + ); + + // STEP 5: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_ModuleRegistry.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_ModuleRegistry.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_ModuleRegistry.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_ModuleRegistry.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the WeightedVoteCheckpointFactory + await I_ModuleRegistry.registerModule(I_WeightedVoteCheckpointFactory.address, { from: account_polymath }); + await I_ModuleRegistry.verifyModule(I_WeightedVoteCheckpointFactory.address, true, { from: account_polymath }); + + // Step 6: Deploy the TickerRegistry + + I_TickerRegistry = await TickerRegistry.new(I_PolyToken.address, initRegFee, { from: account_polymath }); + + assert.notEqual( + I_TickerRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "TickerRegistry contract was not deployed", + ); + + // Step 7: Deploy the STversionProxy contract + + I_STVersion = await STVersion.new(I_GeneralTransferManagerFactory.address); + + assert.notEqual( + I_STVersion.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STVersion contract was not deployed", + ); + + // Step 8: Deploy the SecurityTokenRegistry + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new( + I_PolyToken.address, + I_ModuleRegistry.address, + I_TickerRegistry.address, + I_STVersion.address, + initRegFee, + { + from: account_polymath + }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 8: Set the STR in TickerRegistry + await I_TickerRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistry.address, {from: account_polymath}); + await I_ModuleRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistry.address, {from: account_polymath}); + + // Printing all the contract addresses + console.log(`\nPolymath Network Smart Contracts Deployed:\n + ModuleRegistry: ${I_ModuleRegistry.address}\n + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address}\n + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address}\n + WeightedVoteCheckpointFactory: ${I_WeightedVoteCheckpointFactory.address}\n + TickerRegistry: ${I_TickerRegistry.address}\n + STVersionProxy_001: ${I_STVersion.address}\n + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address}\n + `); + }); + + // describe("Generate the SecurityToken", async() => { + + // it("Should register the ticker before the generation of the security token", async () => { + // await I_PolyToken.approve(I_TickerRegistry.address, initRegFee, { from: token_owner }); + // let tx = await I_TickerRegistry.registerTicker(token_owner, symbol, contact, swarmHash, { from : token_owner }); + // assert.equal(tx.logs[0].args._owner, token_owner); + // assert.equal(tx.logs[0].args._symbol, symbol.toUpperCase()); + // }); + + // it("Should generate the new security token with the same symbol as registered above", async () => { + // await I_PolyToken.approve(I_SecurityTokenRegistry.address, initRegFee, { from: token_owner }); + // let tx = await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + + // // Verify the successful generation of the security token + // assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + // I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + // const LogAddModule = await I_SecurityToken.allEvents(); + // const log = await new Promise(function(resolve, reject) { + // LogAddModule.watch(function(error, log){ resolve(log);}); + // }); + + // // Verify that GeneralTransferManager module get added successfully or not + // assert.equal(log.args._type.toNumber(), 2); + // assert.equal( + // web3.utils.toAscii(log.args._name) + // .replace(/\u0000/g, ''), + // "GeneralTransferManager" + // ); + // LogAddModule.stopWatching(); + // }); + + // it("Should intialize the auto attached modules", async () => { + // let moduleData = await I_SecurityToken.modules(2, 0); + // I_GeneralTransferManager = GeneralTransferManager.at(moduleData[1]); + + // assert.notEqual( + // I_GeneralTransferManager.address.valueOf(), + // "0x0000000000000000000000000000000000000000", + // "GeneralTransferManager contract was not deployed", + // ); + + // }); + + // it("Should fail to attach the WeightedVoteCheckpoint module to the security token if fee not paid", async () => { + // let errorThrown = false; + // await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + // try { + // const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); + // } catch(error) { + // console.log(` tx -> failed because setup fee is not paid`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should successfully attach the WeightedVoteCheckpoint module to the security token", async () => { + // await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + // const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); + // assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); + // assert.equal(web3.utils.hexToUtf8(tx.logs[3].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); + // I_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[3].args._module); + // }); + + // }); + + // describe("Preparation", async() => { + // it("Should successfully mint tokens for first investor account", async() => { + // await I_GeneralTransferManager.modifyWhitelist( + // account_investor1, + // latestTime(), + // latestTime(), + // latestTime() + duration.days(30), + // true, + // { + // from: account_issuer, + // gas: 500000 + // }); + // await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + // }); + + // it("Should successfully mint tokens for second investor account", async() => { + // await I_GeneralTransferManager.modifyWhitelist( + // account_investor2, + // latestTime(), + // latestTime(), + // latestTime() + duration.days(30), + // true, + // { + // from: account_issuer, + // gas: 500000 + // }); + // await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + // }); + // }); + + // describe("Create ballot", async() => { + + // it("Should fail to create a new ballot if not owner", async() => { + // let errorThrown = false; + // try { + // let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: account_temp }); + // } catch(error) { + // console.log(` tx -> failed because msg.sender is not owner`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should successfully create a new ballot", async() => { + // let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: token_owner }); + // assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); + // }); + // }); + + // describe("Create custom ballot", async() => { + + // it("Should fail to create a new custom ballot with endTime before startTime", async() => { + // let errorThrown = false; + // try { + // let startTime = latestTime() + duration.minutes(10); + // let endTime = latestTime() + duration.minutes(5); + // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); + // } catch(error) { + // console.log(` tx -> failed because endTime before startTime`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should fail to create a new custom ballot if checkpointId does not exist", async() => { + // let errorThrown = false; + // try { + // let startTime = latestTime() + duration.minutes(10); + // let endTime = latestTime() + duration.minutes(15); + // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 10, { from: token_owner }); + // } catch(error) { + // console.log(` tx -> failed because checkpointId does not exist`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should fail to create a new custom ballot if not owner", async() => { + // let errorThrown = false; + // try { + // let startTime = latestTime() + duration.minutes(10); + // let endTime = latestTime() + duration.minutes(15); + // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: account_temp }); + // } catch(error) { + // console.log(` tx -> failed because msg.sender is not owner`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should successfully create a new custom ballot", async() => { + // let startTime = latestTime() + duration.minutes(10); + // let endTime = latestTime() + duration.minutes(15); + // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); + // assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); + // }); + // }); + + // describe("Cast vote", async() => { + + // it("Should fail to cast a vote if token balance is zero", async() => { + // let errorThrown = false; + // try { + // let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor3 }); + // } catch(error) { + // console.log(` tx -> failed because token balance is zero`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should fail to cast a vote if voting period has not started", async() => { + // let errorThrown = false; + // try { + // let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); + // } catch(error) { + // console.log(` tx -> failed because voting period has not started`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should fail to cast a vote if voting period has ended", async() => { + // await increaseTime(duration.minutes(20)); + // let errorThrown = false; + // try { + // let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); + // } catch(error) { + // console.log(` tx -> failed because voting period has ended`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should successfully cast a vote from first investor", async() => { + // let tx = await I_WeightedVoteCheckpoint.castVote(false, 0, { from: account_investor1 }); + + // assert.equal(tx.logs[0].args._investor, account_investor1, "Failed to record vote"); + // assert.equal(tx.logs[0].args._vote, false, "Failed to record vote"); + // assert.equal(tx.logs[0].args._weight, web3.utils.toWei('1', 'ether'), "Failed to record vote"); + // assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); + // assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); + // }); + + // it("Should successfully cast a vote from second investor", async() => { + // let tx = await I_WeightedVoteCheckpoint.castVote(true, 0, { from: account_investor2 }); + + // assert.equal(tx.logs[0].args._investor, account_investor2, "Failed to record vote"); + // assert.equal(tx.logs[0].args._vote, true, "Failed to record vote"); + // assert.equal(tx.logs[0].args._weight, web3.utils.toWei('2', 'ether'), "Failed to record vote"); + // assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); + // assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); + // }); + + // it("Should fail to cast a vote again", async() => { + // let errorThrown = false; + // try { + // let tx = await I_WeightedVoteCheckpoint.castVote(false,0, { from: account_investor1 }); + // } catch(error) { + // console.log(` tx -> failed because holder already voted`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + // }); + + // describe("Get results", async() => { + + // it("Should successfully get the results", async() => { + // let tx = await I_WeightedVoteCheckpoint.getResults(0, { from: token_owner }); + // assert.equal(tx[0], web3.utils.toWei('2', 'ether'), "Failed to get results"); + // assert.equal(tx[1], web3.utils.toWei('1', 'ether'), "Failed to get results"); + // assert.equal(tx[2], 0, "Failed to get results"); + // }); + // }); +}); From bfaa674398c316be941b9d067075528a418488b5 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 18:03:52 +0530 Subject: [PATCH 084/142] Fixed migration --- package-lock.json | 4384 +++++++++++++++++++++++---------------------- package.json | 1 + truffle.js | 6 +- 3 files changed, 2204 insertions(+), 2187 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2cace804d..f6b236627 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,14 @@ "integrity": "sha1-JP/ukmQijhw+3WH9MWLWNYeVSTM=", "dev": true, "requires": { - "@soldoc/markdown": "0.1.0", - "chalk": "2.4.1", - "deep-assign": "2.0.0", - "fs-extra": "5.0.0", - "shelljs": "0.8.2", - "solc": "0.4.24", - "valid-url": "1.0.9", - "yargs": "11.0.0" + "@soldoc/markdown": "^0.1.0", + "chalk": "^2.3.1", + "deep-assign": "^2.0.0", + "fs-extra": "^5.0.0", + "shelljs": "^0.8.1", + "solc": "^0.4.19", + "valid-url": "^1.0.9", + "yargs": "^11.0.0" }, "dependencies": { "fs-extra": { @@ -32,9 +32,9 @@ "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } } } @@ -50,7 +50,7 @@ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", "requires": { - "xtend": "4.0.1" + "xtend": "~4.0.0" } }, "accepts": { @@ -58,7 +58,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "2.1.18", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -72,7 +72,7 @@ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", "requires": { - "acorn": "4.0.13" + "acorn": "^4.0.3" }, "dependencies": { "acorn": { @@ -88,7 +88,7 @@ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "dependencies": { "acorn": { @@ -109,10 +109,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "ajv-keywords": { @@ -126,9 +126,9 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" } }, "ambi": { @@ -137,8 +137,8 @@ "integrity": "sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA=", "dev": true, "requires": { - "editions": "1.3.4", - "typechecker": "4.5.0" + "editions": "^1.1.1", + "typechecker": "^4.3.0" }, "dependencies": { "typechecker": { @@ -147,7 +147,7 @@ "integrity": "sha512-bqPE/ck3bVIaXP7gMKTKSHrypT32lpYTpiqzPYeYzdSQnmaGvaGhy7TnN/M/+5R+2rs/kKcp9ZLPRp/Q9Yj+4w==", "dev": true, "requires": { - "editions": "1.3.4" + "editions": "^1.3.4" } } } @@ -174,7 +174,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "any-promise": { @@ -188,8 +188,8 @@ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" } }, "argparse": { @@ -197,7 +197,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "arguments-extended": { @@ -206,8 +206,8 @@ "integrity": "sha1-YQfkkX0OtvCk3WYyD8Fa/HLvSUY=", "dev": true, "requires": { - "extended": "0.0.6", - "is-extended": "0.0.10" + "extended": "~0.0.3", + "is-extended": "~0.0.8" } }, "arr-diff": { @@ -216,7 +216,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "1.1.0" + "arr-flatten": "^1.0.1" } }, "arr-flatten": { @@ -235,9 +235,9 @@ "integrity": "sha1-1xRK50jek8pybxIQCdv/FibRZL0=", "dev": true, "requires": { - "arguments-extended": "0.0.3", - "extended": "0.0.6", - "is-extended": "0.0.10" + "arguments-extended": "~0.0.3", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "array-flatten": { @@ -251,7 +251,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { @@ -288,9 +288,9 @@ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "requires": { - "bn.js": "4.11.6", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "assert": { @@ -326,7 +326,7 @@ "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", "requires": { - "async": "2.6.0" + "async": "^2.4.0" }, "dependencies": { "async": { @@ -334,7 +334,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } } } @@ -369,9 +369,9 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" }, "dependencies": { "ansi-styles": { @@ -384,11 +384,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "supports-color": { @@ -403,25 +403,25 @@ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.1", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.5.1", - "debug": "2.6.9", - "json5": "0.5.1", - "lodash": "4.17.5", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.8", - "slash": "1.0.0", - "source-map": "0.5.7" + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" } }, "babel-generator": { @@ -429,14 +429,14 @@ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.5", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" }, "dependencies": { "jsesc": { @@ -451,9 +451,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -461,9 +461,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", "requires": { - "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-call-delegate": { @@ -471,10 +471,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-define-map": { @@ -482,10 +482,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.5" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, "babel-helper-explode-assignable-expression": { @@ -493,9 +493,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-explode-class": { @@ -503,10 +503,10 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", "requires": { - "babel-helper-bindify-decorators": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-function-name": { @@ -514,11 +514,11 @@ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-get-function-arity": { @@ -526,8 +526,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-hoist-variables": { @@ -535,8 +535,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-optimise-call-expression": { @@ -544,8 +544,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-helper-regex": { @@ -553,9 +553,9 @@ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.5" + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, "babel-helper-remap-async-to-generator": { @@ -563,11 +563,11 @@ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helper-replace-supers": { @@ -575,12 +575,12 @@ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-helpers": { @@ -588,8 +588,8 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-messages": { @@ -597,7 +597,7 @@ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-check-es2015-constants": { @@ -605,7 +605,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-syntax-async-functions": { @@ -653,9 +653,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-generators": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-async-to-generator": { @@ -663,9 +663,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-class-properties": { @@ -673,10 +673,10 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-plugin-syntax-class-properties": "6.13.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-decorators": { @@ -684,11 +684,11 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", "requires": { - "babel-helper-explode-class": "6.24.1", - "babel-plugin-syntax-decorators": "6.13.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -696,7 +696,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -704,7 +704,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -712,11 +712,11 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.5" + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, "babel-plugin-transform-es2015-classes": { @@ -724,15 +724,15 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "requires": { - "babel-helper-define-map": "6.26.0", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -740,8 +740,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-destructuring": { @@ -749,7 +749,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -757,8 +757,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-for-of": { @@ -766,7 +766,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -774,9 +774,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-literals": { @@ -784,7 +784,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -792,9 +792,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -802,10 +802,10 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -813,9 +813,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -823,9 +823,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, "babel-plugin-transform-es2015-object-super": { @@ -833,8 +833,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.26.0" + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -842,12 +842,12 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -855,8 +855,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-spread": { @@ -864,7 +864,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -872,9 +872,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-plugin-transform-es2015-template-literals": { @@ -882,7 +882,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -890,7 +890,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -898,9 +898,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "regexpu-core": "2.0.0" + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" } }, "babel-plugin-transform-exponentiation-operator": { @@ -908,9 +908,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", - "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.26.0" + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" } }, "babel-plugin-transform-object-rest-spread": { @@ -918,8 +918,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", "requires": { - "babel-plugin-syntax-object-rest-spread": "6.13.0", - "babel-runtime": "6.26.0" + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" } }, "babel-plugin-transform-regenerator": { @@ -927,7 +927,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "requires": { - "regenerator-transform": "0.10.1" + "regenerator-transform": "^0.10.0" } }, "babel-plugin-transform-strict-mode": { @@ -935,8 +935,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, "babel-polyfill": { @@ -944,9 +944,9 @@ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "requires": { - "babel-runtime": "6.26.0", - "core-js": "2.5.3", - "regenerator-runtime": "0.10.5" + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" } }, "babel-preset-env": { @@ -954,36 +954,36 @@ "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.11.3", - "invariant": "2.2.3", - "semver": "5.5.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^2.1.2", + "invariant": "^2.2.2", + "semver": "^5.3.0" } }, "babel-preset-es2015": { @@ -991,30 +991,30 @@ "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0" + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" } }, "babel-preset-stage-2": { @@ -1022,10 +1022,10 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", "requires": { - "babel-plugin-syntax-dynamic-import": "6.18.0", - "babel-plugin-transform-class-properties": "6.24.1", - "babel-plugin-transform-decorators": "6.24.1", - "babel-preset-stage-3": "6.24.1" + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" } }, "babel-preset-stage-3": { @@ -1033,11 +1033,11 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", "requires": { - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-generator-functions": "6.24.1", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-object-rest-spread": "6.26.0" + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" } }, "babel-register": { @@ -1045,13 +1045,13 @@ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "requires": { - "babel-core": "6.26.0", - "babel-runtime": "6.26.0", - "core-js": "2.5.3", - "home-or-tmp": "2.0.0", - "lodash": "4.17.5", - "mkdirp": "0.5.1", - "source-map-support": "0.4.18" + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" } }, "babel-runtime": { @@ -1059,8 +1059,8 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.5.3", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { "regenerator-runtime": { @@ -1075,11 +1075,11 @@ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.5" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, "babel-traverse": { @@ -1087,15 +1087,15 @@ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.3", - "lodash": "4.17.5" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" } }, "babel-types": { @@ -1103,10 +1103,10 @@ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.5", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, "babelify": { @@ -1114,8 +1114,8 @@ "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { - "babel-core": "6.26.0", - "object-assign": "4.1.1" + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" } }, "babylon": { @@ -1133,13 +1133,13 @@ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -1147,7 +1147,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -1155,7 +1155,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -1163,7 +1163,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -1171,9 +1171,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -1204,7 +1204,7 @@ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "big.js": { @@ -1232,7 +1232,7 @@ "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "bitcore-lib": { @@ -1241,12 +1241,12 @@ "integrity": "sha512-AeXLWhiivF6CDFzrABZHT4jJrflyylDWTi32o30rF92HW9msfuKpjzrHtFKYGa9w0kNVv5HABQjCB3OEav4PhQ==", "dev": true, "requires": { - "bn.js": "4.11.8", - "bs58": "4.0.1", - "buffer-compare": "1.1.1", - "elliptic": "6.4.0", - "inherits": "2.0.1", - "lodash": "4.17.4" + "bn.js": "=4.11.8", + "bs58": "=4.0.1", + "buffer-compare": "=1.1.1", + "elliptic": "=6.4.0", + "inherits": "=2.0.1", + "lodash": "=4.17.4" }, "dependencies": { "base-x": { @@ -1255,7 +1255,7 @@ "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "bn.js": { @@ -1270,7 +1270,7 @@ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dev": true, "requires": { - "base-x": "3.0.4" + "base-x": "^3.0.2" } }, "inherits": { @@ -1293,8 +1293,8 @@ "integrity": "sha512-sbeP4xwkindLMfIQhVxj6rZSDMwtiKmfc1DqvwpR6Yg+Qo4I4WHO5pvzb12Y04uDh1N3zgD45esHhfH0HHmE4g==", "dev": true, "requires": { - "bitcore-lib": "0.15.0", - "unorm": "1.4.1" + "bitcore-lib": "^0.15.0", + "unorm": "^1.3.3" } }, "bl": { @@ -1302,8 +1302,8 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { - "readable-stream": "2.3.5", - "safe-buffer": "5.1.1" + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" } }, "block-stream": { @@ -1311,7 +1311,7 @@ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "bluebird": { @@ -1330,15 +1330,15 @@ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.2", + "depd": "~1.1.1", + "http-errors": "~1.6.2", "iconv-lite": "0.4.19", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.1", "raw-body": "2.3.2", - "type-is": "1.6.16" + "type-is": "~1.6.15" } }, "boom": { @@ -1346,7 +1346,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "borc": { @@ -1355,10 +1355,10 @@ "integrity": "sha512-2mfipKUXn7yLgwn8D5jZkJqd2ZyzqmYZQX/9d4On33oGNDLwxj5qQMst+nkKyEdaujQRFfrZCId+k8wehQVANg==", "dev": true, "requires": { - "bignumber.js": "6.0.0", - "commander": "2.16.0", - "ieee754": "1.1.10", - "json-text-sequence": "0.1.1" + "bignumber.js": "^6.0.0", + "commander": "^2.15.0", + "ieee754": "^1.1.8", + "json-text-sequence": "^0.1" }, "dependencies": { "bignumber.js": { @@ -1380,7 +1380,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -1390,9 +1390,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" } }, "brorand": { @@ -1411,12 +1411,12 @@ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "browserify-cipher": { @@ -1424,9 +1424,9 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "requires": { - "browserify-aes": "1.1.1", - "browserify-des": "1.0.0", - "evp_bytestokey": "1.0.3" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, "browserify-des": { @@ -1434,9 +1434,9 @@ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.3" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1" } }, "browserify-rsa": { @@ -1444,8 +1444,8 @@ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { - "bn.js": "4.11.6", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, "browserify-sha3": { @@ -1453,7 +1453,7 @@ "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", "requires": { - "js-sha3": "0.3.1" + "js-sha3": "^0.3.1" }, "dependencies": { "js-sha3": { @@ -1468,13 +1468,13 @@ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "requires": { - "bn.js": "4.11.6", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "elliptic": "6.4.0", - "inherits": "2.0.3", - "parse-asn1": "5.1.0" + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" } }, "browserify-zlib": { @@ -1482,7 +1482,7 @@ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "requires": { - "pako": "1.0.6" + "pako": "~1.0.5" } }, "browserslist": { @@ -1490,8 +1490,8 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", "requires": { - "caniuse-lite": "1.0.30000819", - "electron-to-chromium": "1.3.40" + "caniuse-lite": "^1.0.30000792", + "electron-to-chromium": "^1.3.30" } }, "bs58": { @@ -1499,7 +1499,7 @@ "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", "requires": { - "base-x": "1.1.0" + "base-x": "^1.1.0" } }, "bs58check": { @@ -1507,8 +1507,8 @@ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", "requires": { - "bs58": "3.1.0", - "create-hash": "1.1.3" + "bs58": "^3.1.0", + "create-hash": "^1.1.0" } }, "bson": { @@ -1523,8 +1523,8 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.10" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, "buffer-compare": { @@ -1574,15 +1574,15 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" }, "dependencies": { "isobject": { @@ -1598,7 +1598,7 @@ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "0.2.0" + "callsites": "^0.2.0" } }, "callsites": { @@ -1618,8 +1618,8 @@ "integrity": "sha1-7B7ARXZkoPCSZDt8ZGxFfVzW9pM=", "dev": true, "requires": { - "bluebird": "3.5.1", - "uuid": "3.2.1" + "bluebird": "^3.4.6", + "uuid": "^3.0.1" } }, "caniuse-lite": { @@ -1637,8 +1637,8 @@ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" } }, "chalk": { @@ -1646,9 +1646,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.4.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "chardet": { @@ -1662,7 +1662,7 @@ "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", "requires": { - "functional-red-black-tree": "1.0.1" + "functional-red-black-tree": "^1.0.1" } }, "chokidar": { @@ -1671,15 +1671,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.1.3", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" } }, "cipher-base": { @@ -1687,8 +1687,8 @@ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "circular-json": { @@ -1702,10 +1702,10 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -1713,7 +1713,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "isobject": { @@ -1729,12 +1729,12 @@ "integrity": "sha1-OlrnT9drYmevZm5p4q+70B3vNNE=", "dev": true, "requires": { - "ansi-regex": "2.1.1", - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", - "memoizee": "0.4.12", - "timers-ext": "0.1.3" + "ansi-regex": "^2.1.1", + "d": "1", + "es5-ext": "^0.10.12", + "es6-iterator": "2", + "memoizee": "^0.4.3", + "timers-ext": "0.1" } }, "cli-cursor": { @@ -1743,7 +1743,7 @@ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { - "restore-cursor": "2.0.0" + "restore-cursor": "^2.0.0" } }, "cli-width": { @@ -1758,9 +1758,9 @@ "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", "dev": true, "requires": { - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "wrap-ansi": "2.1.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" }, "dependencies": { "ansi-regex": { @@ -1775,7 +1775,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -1795,8 +1795,8 @@ "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", "requires": { - "bs58": "2.0.1", - "create-hash": "1.1.3" + "bs58": "^2.0.1", + "create-hash": "^1.1.1" }, "dependencies": { "bs58": { @@ -1811,8 +1811,8 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -1820,7 +1820,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "requires": { - "color-name": "1.1.3" + "color-name": "^1.1.1" } }, "color-name": { @@ -1839,7 +1839,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -1869,10 +1869,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "1.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.5", - "typedarray": "0.0.6" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "console-browserify": { @@ -1880,7 +1880,7 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "requires": { - "date-now": "0.1.4" + "date-now": "^0.1.4" } }, "constants-browserify": { @@ -1939,8 +1939,8 @@ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", "requires": { - "object-assign": "4.1.1", - "vary": "1.1.2" + "object-assign": "^4", + "vary": "^1" } }, "coveralls": { @@ -1948,11 +1948,11 @@ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", "requires": { - "js-yaml": "3.11.0", - "lcov-parse": "0.0.10", - "log-driver": "1.2.7", - "minimist": "1.2.0", - "request": "2.85.0" + "js-yaml": "^3.6.1", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.5", + "minimist": "^1.2.0", + "request": "^2.79.0" }, "dependencies": { "minimist": { @@ -1967,8 +1967,8 @@ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", "requires": { - "bn.js": "4.11.6", - "elliptic": "6.4.0" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, "create-hash": { @@ -1976,10 +1976,10 @@ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "sha.js": "2.4.10" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "sha.js": "^2.4.0" } }, "create-hmac": { @@ -1987,12 +1987,12 @@ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "cron-parser": { @@ -2001,8 +2001,8 @@ "integrity": "sha512-gzmXu16/prizIbKPPKJo+WgBpV7k8Rxxu9FgaANW+vx5DebCXavfRqbROjKkr9ETvVPqs+IO+NXj4GG/eLf8zQ==", "dev": true, "requires": { - "is-nan": "1.2.1", - "moment-timezone": "0.5.21" + "is-nan": "^1.2.1", + "moment-timezone": "^0.5.0" } }, "cryptiles": { @@ -2010,7 +2010,7 @@ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "requires": { - "boom": "5.2.0" + "boom": "5.x.x" }, "dependencies": { "boom": { @@ -2018,7 +2018,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } } } @@ -2028,17 +2028,17 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "requires": { - "browserify-cipher": "1.0.0", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", - "inherits": "2.0.3", - "pbkdf2": "3.0.14", - "public-encrypt": "4.0.0", - "randombytes": "2.0.6", - "randomfill": "1.0.4" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, "crypto-js": { @@ -2069,7 +2069,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "0.10.39" + "es5-ext": "^0.10.9" } }, "dashdash": { @@ -2077,7 +2077,7 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "date-extended": { @@ -2086,9 +2086,9 @@ "integrity": "sha1-I4AtV90b94GIE/4MMuhRqG2iZ8k=", "dev": true, "requires": { - "array-extended": "0.0.11", - "extended": "0.0.6", - "is-extended": "0.0.10" + "array-extended": "~0.0.3", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "date-now": { @@ -2131,14 +2131,14 @@ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", "requires": { - "decompress-tar": "4.1.1", - "decompress-tarbz2": "4.1.1", - "decompress-targz": "4.1.1", - "decompress-unzip": "4.0.1", - "graceful-fs": "4.1.11", - "make-dir": "1.2.0", - "pify": "2.3.0", - "strip-dirs": "2.1.0" + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" }, "dependencies": { "pify": { @@ -2153,7 +2153,7 @@ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "requires": { - "mimic-response": "1.0.0" + "mimic-response": "^1.0.0" } }, "decompress-tar": { @@ -2161,9 +2161,9 @@ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "requires": { - "file-type": "5.2.0", - "is-stream": "1.1.0", - "tar-stream": "1.5.5" + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" } }, "decompress-tarbz2": { @@ -2171,11 +2171,11 @@ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "requires": { - "decompress-tar": "4.1.1", - "file-type": "6.2.0", - "is-stream": "1.1.0", - "seek-bzip": "1.0.5", - "unbzip2-stream": "1.2.5" + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" }, "dependencies": { "file-type": { @@ -2190,9 +2190,9 @@ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "requires": { - "decompress-tar": "4.1.1", - "file-type": "5.2.0", - "is-stream": "1.1.0" + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" } }, "decompress-unzip": { @@ -2200,10 +2200,10 @@ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", "requires": { - "file-type": "3.9.0", - "get-stream": "2.3.1", - "pify": "2.3.0", - "yauzl": "2.9.1" + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" }, "dependencies": { "file-type": { @@ -2216,8 +2216,8 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "requires": { - "object-assign": "4.1.1", - "pinkie-promise": "2.0.1" + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -2233,7 +2233,7 @@ "integrity": "sha1-6+BrHwfwja5ZdiDj3RYi83GhxXI=", "dev": true, "requires": { - "is-obj": "1.0.1" + "is-obj": "^1.0.0" } }, "deep-equal": { @@ -2252,7 +2252,7 @@ "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", "requires": { - "abstract-leveldown": "2.6.3" + "abstract-leveldown": "~2.6.0" } }, "define-properties": { @@ -2260,8 +2260,8 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.11" + "foreach": "^2.0.5", + "object-keys": "^1.0.8" }, "dependencies": { "object-keys": { @@ -2276,8 +2276,8 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -2285,7 +2285,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2293,7 +2293,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2301,9 +2301,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -2329,13 +2329,13 @@ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.1", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.2.8" + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" }, "dependencies": { "globby": { @@ -2344,12 +2344,12 @@ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -2381,8 +2381,8 @@ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "destroy": { @@ -2395,7 +2395,7 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "diff": { @@ -2409,9 +2409,9 @@ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "requires": { - "bn.js": "4.11.6", - "miller-rabin": "4.0.1", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, "doctrine": { @@ -2420,7 +2420,7 @@ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "2.0.2" + "esutils": "^2.0.2" } }, "dom-walk": { @@ -2438,9 +2438,9 @@ "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", "requires": { - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6" + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" } }, "duplexer3": { @@ -2454,7 +2454,7 @@ "integrity": "sha1-Rm98qhBwj2EFCeMsgHqv5X/BIr8=", "dev": true, "requires": { - "typechecker": "2.1.0" + "typechecker": "^2.0.8" } }, "ecc-jsbn": { @@ -2463,7 +2463,7 @@ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "editions": { @@ -2487,13 +2487,13 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "requires": { - "bn.js": "4.11.6", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, "emojis-list": { @@ -2511,7 +2511,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "0.4.19" + "iconv-lite": "~0.4.13" } }, "end-of-stream": { @@ -2519,7 +2519,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { - "once": "1.4.0" + "once": "^1.4.0" } }, "errno": { @@ -2527,7 +2527,7 @@ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "requires": { - "prr": "1.0.1" + "prr": "~1.0.1" } }, "error-ex": { @@ -2535,7 +2535,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "es-abstract": { @@ -2543,11 +2543,11 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" } }, "es-to-primitive": { @@ -2555,9 +2555,9 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" } }, "es5-ext": { @@ -2565,8 +2565,8 @@ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.39.tgz", "integrity": "sha512-AlaXZhPHl0po/uxMx1tyrlt1O86M6D5iVaDH8UgLfgek4kXTX6vzsRfJQWC2Ku+aG8pkw1XWzh9eTkwfVrsD5g==", "requires": { - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1" } }, "es6-iterator": { @@ -2574,9 +2574,9 @@ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, "es6-map": { @@ -2584,12 +2584,12 @@ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" } }, "es6-set": { @@ -2597,11 +2597,11 @@ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "event-emitter": "~0.3.5" } }, "es6-symbol": { @@ -2609,8 +2609,8 @@ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39" + "d": "1", + "es5-ext": "~0.10.14" } }, "es6-weak-map": { @@ -2618,10 +2618,10 @@ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" } }, "escape-html": { @@ -2640,11 +2640,11 @@ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { - "esprima": "2.7.3", - "estraverse": "1.9.3", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.2.0" + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" }, "dependencies": { "esprima": { @@ -2666,7 +2666,7 @@ "dev": true, "optional": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -2676,10 +2676,10 @@ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint": { @@ -2688,44 +2688,44 @@ "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { - "ajv": "5.5.2", - "babel-code-frame": "6.26.0", - "chalk": "2.3.2", - "concat-stream": "1.6.2", - "cross-spawn": "5.1.0", - "debug": "3.1.0", - "doctrine": "2.1.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0", - "espree": "3.5.4", - "esquery": "1.0.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "11.4.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "3.3.0", - "is-resolvable": "1.1.0", - "js-yaml": "3.11.0", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.5", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "regexpp": "1.1.0", - "require-uncached": "1.0.3", - "semver": "5.5.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", "table": "4.0.2", - "text-table": "0.2.0" + "text-table": "~0.2.0" }, "dependencies": { "ansi-regex": { @@ -2740,7 +2740,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -2749,9 +2749,9 @@ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "cross-spawn": { @@ -2760,9 +2760,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.2", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "debug": { @@ -2786,20 +2786,20 @@ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.3.2", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.1.0", - "figures": "2.0.0", - "lodash": "4.17.5", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" } }, "strip-ansi": { @@ -2808,7 +2808,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "supports-color": { @@ -2817,7 +2817,7 @@ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -2834,8 +2834,8 @@ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", "dev": true, "requires": { - "debug": "2.6.9", - "resolve": "1.5.0" + "debug": "^2.6.9", + "resolve": "^1.5.0" } }, "eslint-module-utils": { @@ -2844,8 +2844,8 @@ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", "dev": true, "requires": { - "debug": "2.6.9", - "pkg-dir": "1.0.0" + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" } }, "eslint-plugin-import": { @@ -2854,16 +2854,16 @@ "integrity": "sha1-+gkIPVp1KI35xsfQn+EiVZhWVec=", "dev": true, "requires": { - "builtin-modules": "1.1.1", - "contains-path": "0.1.0", - "debug": "2.6.9", + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.2", - "eslint-module-utils": "2.2.0", - "has": "1.0.1", - "lodash": "4.17.5", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0" + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.2.0", + "has": "^1.0.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" }, "dependencies": { "doctrine": { @@ -2872,8 +2872,8 @@ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "esutils": "^2.0.2", + "isarray": "^1.0.0" } }, "load-json-file": { @@ -2882,10 +2882,10 @@ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, "parse-json": { @@ -2894,7 +2894,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-type": { @@ -2903,7 +2903,7 @@ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { - "pify": "2.3.0" + "pify": "^2.0.0" } }, "pify": { @@ -2918,9 +2918,9 @@ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "read-pkg-up": { @@ -2929,8 +2929,8 @@ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "strip-bom": { @@ -2947,10 +2947,10 @@ "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", "dev": true, "requires": { - "ignore": "3.3.7", - "minimatch": "3.0.4", - "resolve": "1.5.0", - "semver": "5.5.0" + "ignore": "^3.3.6", + "minimatch": "^3.0.4", + "resolve": "^1.3.3", + "semver": "^5.4.1" } }, "eslint-plugin-promise": { @@ -2971,8 +2971,8 @@ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint-visitor-keys": { @@ -2987,8 +2987,8 @@ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { - "acorn": "5.5.3", - "acorn-jsx": "3.0.1" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, "esprima": { @@ -3002,7 +3002,7 @@ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { @@ -3010,7 +3010,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.1.0" } }, "estraverse": { @@ -3034,13 +3034,13 @@ "integrity": "sha512-yrNyBIBKC7WfUjrXSG/CZVy0gW2aF8+MnjnrkOxkZOR+BAtL6JgYOnzVnrU8KE6mKJETlA/1dYMygvLXWyJGGw==", "requires": { "async-eventemitter": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "eth-query": "2.1.2", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "ethjs-util": "0.1.4", - "json-rpc-engine": "3.6.1", - "pify": "2.3.0", - "tape": "4.9.0" + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" }, "dependencies": { "async": { @@ -3048,13 +3048,14 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "async-eventemitter": { "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", + "from": "async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", "requires": { - "async": "2.6.0" + "async": "^2.4.0" } }, "ethereumjs-util": { @@ -3062,13 +3063,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "pify": { @@ -3083,13 +3084,13 @@ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", "requires": { - "bn.js": "4.11.6", - "elliptic": "6.4.0", - "keccakjs": "0.2.1", - "nano-json-stream-parser": "0.1.2", - "servify": "0.1.12", - "ws": "3.3.3", - "xhr-request-promise": "0.1.2" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "keccakjs": "^0.2.1", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" } }, "eth-lightwallet": { @@ -3098,21 +3099,22 @@ "integrity": "sha512-79vVCETy+4l1b6wuOWwjqPW3Bom5ZK46BgkUNwaXhiMG1rrMRHjpjYEWMqH0JHeCzOzB4HBIFz7eK1/4s6w5nA==", "dev": true, "requires": { - "bitcore-lib": "0.15.0", - "bitcore-mnemonic": "1.5.0", - "buffer": "4.9.1", - "crypto-js": "3.1.8", - "elliptic": "3.1.0", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.2.0", - "rlp": "2.0.0", - "scrypt-async": "1.3.1", + "bitcore-lib": "^0.15.0", + "bitcore-mnemonic": "^1.5.0", + "buffer": "^4.9.0", + "crypto-js": "^3.1.5", + "elliptic": "^3.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.1", + "rlp": "^2.0.0", + "scrypt-async": "^1.2.0", "tweetnacl": "0.13.2", "web3": "0.20.2" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "dev": true }, "bn.js": { @@ -3127,9 +3129,9 @@ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.10", - "isarray": "1.0.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "elliptic": { @@ -3138,10 +3140,10 @@ "integrity": "sha1-whaC73YnabVqdCAWCRBdoR1fYMw=", "dev": true, "requires": { - "bn.js": "2.2.0", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "inherits": "2.0.3" + "bn.js": "^2.0.3", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" } }, "ethereumjs-util": { @@ -3150,13 +3152,13 @@ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "4.11.8", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" }, "dependencies": { "bn.js": { @@ -3180,10 +3182,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -3193,8 +3195,8 @@ "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", "requires": { - "json-rpc-random-id": "1.0.1", - "xtend": "4.0.1" + "json-rpc-random-id": "^1.0.0", + "xtend": "^4.0.1" } }, "eth-sig-util": { @@ -3203,14 +3205,15 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "ethereumjs-util": "5.1.5" + "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", + "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", "requires": { - "bn.js": "4.11.6", - "ethereumjs-util": "5.1.5" + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" } }, "ethereumjs-util": { @@ -3218,13 +3221,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3235,31 +3238,31 @@ "integrity": "sha512-yDTivI85618BoLI71yNRzW6iVcVN2rjnviCIzs0QOCOENj4XpYQhMDGhdqDi8XWDdzTd0Ja/Canuuh3vfE2IcA==", "dev": true, "requires": { - "async": "2.6.1", - "borc": "2.0.3", + "async": "^2.4.1", + "borc": "^2.0.2", "caminte": "0.3.7", - "colors": "1.2.1", - "compare-versions": "3.3.0", - "crypto-random-string": "1.0.0", - "eth-lightwallet": "3.0.1", + "colors": "^1.1.2", + "compare-versions": "^3.0.1", + "crypto-random-string": "^1.0.0", + "eth-lightwallet": "^3.0.1", "ethereumjs-abi": "0.6.4", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.2.0", - "i18n": "0.8.3", - "moment": "2.22.2", - "multihashes": "0.4.13", - "node-async-loop": "1.2.2", - "node-cache": "4.2.0", - "node-schedule": "1.3.0", + "ethereumjs-tx": "^1.3.1", + "ethereumjs-util": "^5.2.0", + "i18n": "^0.8.3", + "moment": "^2.22.2", + "multihashes": "^0.4.5", + "node-async-loop": "^1.2.2", + "node-cache": "^4.1.1", + "node-schedule": "^1.2.3", "pragma-singleton": "1.0.3", - "request": "2.85.0", - "semver": "5.5.0", - "stdio": "0.2.7", - "tingodb": "0.6.1", - "underscore": "1.9.1", - "utf8": "2.1.2", + "request": "^2.81.0", + "semver": "^5.5.0", + "stdio": "^0.2.7", + "tingodb": "^0.6.1", + "underscore": "^1.8.3", + "utf8": "^2.1.2", "web3": "0.19.1", - "winston": "2.4.3" + "winston": "^2.3.1" }, "dependencies": { "async": { @@ -3268,7 +3271,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "4.17.10" + "lodash": "^4.17.10" } }, "bignumber.js": { @@ -3283,8 +3286,8 @@ "integrity": "sha1-m6G7BWSS0AwnJ59uzNTVgnWRLBo=", "dev": true, "requires": { - "bn.js": "4.11.6", - "ethereumjs-util": "4.5.0" + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" }, "dependencies": { "ethereumjs-util": { @@ -3293,11 +3296,11 @@ "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "dev": true, "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "keccakjs": "0.2.1", - "rlp": "2.0.0", - "secp256k1": "3.5.0" + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "keccakjs": "^0.2.0", + "rlp": "^2.0.0", + "secp256k1": "^3.0.1" } } } @@ -3308,13 +3311,13 @@ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", "dev": true, "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "lodash": { @@ -3341,11 +3344,11 @@ "integrity": "sha1-52PVsRB8S8JKvU+MvuG6Nlnm6zE=", "dev": true, "requires": { - "bignumber.js": "4.1.0", - "crypto-js": "3.1.8", - "utf8": "2.1.2", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "bignumber.js": "^4.0.2", + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -3361,8 +3364,8 @@ "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", "dev": true, "requires": { - "bn.js": "4.11.6", - "ethereumjs-util": "4.5.0" + "bn.js": "^4.10.0", + "ethereumjs-util": "^4.3.0" } }, "ethereumjs-account": { @@ -3370,8 +3373,8 @@ "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.4.tgz", "integrity": "sha1-+MMCMby3B/RRTYoFLB+doQNiTUc=", "requires": { - "ethereumjs-util": "4.5.0", - "rlp": "2.0.0" + "ethereumjs-util": "^4.0.1", + "rlp": "^2.0.0" } }, "ethereumjs-block": { @@ -3379,11 +3382,11 @@ "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", "requires": { - "async": "2.6.0", + "async": "^2.0.1", "ethereum-common": "0.2.0", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "merkle-patricia-tree": "2.3.1" + "ethereumjs-tx": "^1.2.2", + "ethereumjs-util": "^5.0.0", + "merkle-patricia-tree": "^2.1.2" }, "dependencies": { "async": { @@ -3391,7 +3394,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "ethereumjs-util": { @@ -3399,13 +3402,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3415,7 +3418,7 @@ "resolved": "https://registry.npmjs.org/ethereumjs-testrpc/-/ethereumjs-testrpc-6.0.3.tgz", "integrity": "sha512-lAxxsxDKK69Wuwqym2K49VpXtBvLEsXr1sryNG4AkvL5DomMdeCBbu3D87UEevKenLHBiT8GTjARwN6Yj039gA==", "requires": { - "webpack": "3.11.0" + "webpack": "^3.0.0" } }, "ethereumjs-testrpc-sc": { @@ -3424,7 +3427,7 @@ "integrity": "sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg==", "dev": true, "requires": { - "source-map-support": "0.5.9" + "source-map-support": "^0.5.3" }, "dependencies": { "source-map": { @@ -3439,8 +3442,8 @@ "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "buffer-from": "1.0.0", - "source-map": "0.6.1" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } } } @@ -3450,8 +3453,8 @@ "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz", "integrity": "sha512-kOgUd5jC+0tgV7t52UDECMMz9Uf+Lro+6fSpCvzWemtXfMEcwI3EOxf5mVPMRbTFkMMhuERokNNVF3jItAjidg==", "requires": { - "ethereum-common": "0.0.18", - "ethereumjs-util": "5.1.5" + "ethereum-common": "^0.0.18", + "ethereumjs-util": "^5.0.0" }, "dependencies": { "ethereum-common": { @@ -3464,13 +3467,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3480,11 +3483,11 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "keccakjs": "0.2.1", - "rlp": "2.0.0", - "secp256k1": "3.5.0" + "bn.js": "^4.8.0", + "create-hash": "^1.1.2", + "keccakjs": "^0.2.0", + "rlp": "^2.0.0", + "secp256k1": "^3.0.1" } }, "ethereumjs-vm": { @@ -3492,17 +3495,17 @@ "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.3.tgz", "integrity": "sha512-yIWJqTEcrF9vJTCvNMxacRkAx6zIZTOW0SmSA+hSFiU1x8JyVZDi9o5udwsRVECT5RkPgQzm62kpL6Pf4qemsw==", "requires": { - "async": "2.6.0", - "async-eventemitter": "0.2.4", + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", "ethereum-common": "0.2.0", - "ethereumjs-account": "2.0.4", - "ethereumjs-block": "1.7.1", - "ethereumjs-util": "5.1.5", - "fake-merkle-patricia-tree": "1.0.1", - "functional-red-black-tree": "1.0.1", - "merkle-patricia-tree": "2.3.1", - "rustbn.js": "0.1.2", - "safe-buffer": "5.1.1" + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~1.7.0", + "ethereumjs-util": "^5.1.3", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.1.2", + "rustbn.js": "~0.1.1", + "safe-buffer": "^5.1.1" }, "dependencies": { "async": { @@ -3510,7 +3513,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "ethereumjs-util": { @@ -3518,13 +3521,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -3534,13 +3537,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", "requires": { - "aes-js": "0.2.4", - "bs58check": "1.3.4", - "ethereumjs-util": "4.5.0", - "hdkey": "0.7.1", - "scrypt.js": "0.2.0", - "utf8": "2.1.1", - "uuid": "2.0.3" + "aes-js": "^0.2.3", + "bs58check": "^1.0.8", + "ethereumjs-util": "^4.4.0", + "hdkey": "^0.7.0", + "scrypt.js": "^0.2.0", + "utf8": "^2.1.1", + "uuid": "^2.0.1" }, "dependencies": { "uuid": { @@ -3556,9 +3559,9 @@ "integrity": "sha512-d/tiMUavaeaY2GFqjpgfPzT46cEc0cilP3hnlTXR3LR/HR5Qrhv4PfdgW3gxBlR5aBTtUeM/lo8z8ph3JdtFhQ==", "requires": { "aes-js": "3.0.0", - "bn.js": "4.11.6", + "bn.js": "^4.4.0", "elliptic": "6.3.3", - "hash.js": "1.1.3", + "hash.js": "^1.0.0", "inherits": "2.0.1", "js-sha3": "0.5.7", "scrypt-js": "2.0.3", @@ -3577,10 +3580,10 @@ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", "requires": { - "bn.js": "4.11.6", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "inherits": "2.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" } }, "inherits": { @@ -3628,8 +3631,8 @@ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39" + "d": "1", + "es5-ext": "~0.10.14" } }, "eventemitter3": { @@ -3647,8 +3650,8 @@ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "requires": { - "md5.js": "1.3.4", - "safe-buffer": "5.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, "execa": { @@ -3656,13 +3659,13 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" }, "dependencies": { "cross-spawn": { @@ -3670,9 +3673,9 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "requires": { - "lru-cache": "4.1.2", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } } } @@ -3683,7 +3686,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "is-posix-bracket": "^0.1.0" } }, "expand-range": { @@ -3692,7 +3695,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.3" + "fill-range": "^2.1.0" } }, "express": { @@ -3700,36 +3703,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.2", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.3", + "proxy-addr": "~2.0.3", "qs": "6.5.1", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.1", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" }, "dependencies": { "setprototypeof": { @@ -3749,8 +3752,8 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -3758,7 +3761,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -3769,7 +3772,7 @@ "integrity": "sha1-f7i/e52uOXWG5IVwrP1kLHjlBmk=", "dev": true, "requires": { - "extender": "0.0.10" + "extender": "~0.0.5" } }, "extender": { @@ -3778,7 +3781,7 @@ "integrity": "sha1-WJwHSCvmGhRgttgfnCSqZ+jzJM0=", "dev": true, "requires": { - "declare.js": "0.0.8" + "declare.js": "~0.0.4" } }, "extendr": { @@ -3787,7 +3790,7 @@ "integrity": "sha1-MBqgu+pWX00tyPVw8qImEahSe1Y=", "dev": true, "requires": { - "typechecker": "2.0.8" + "typechecker": "~2.0.1" }, "dependencies": { "typechecker": { @@ -3804,9 +3807,9 @@ "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", "dev": true, "requires": { - "chardet": "0.4.2", - "iconv-lite": "0.4.19", - "tmp": "0.0.33" + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" } }, "extglob": { @@ -3815,7 +3818,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "extract-opts": { @@ -3824,7 +3827,7 @@ "integrity": "sha1-H6KOunNSxttID4hc63GkaBC+bX0=", "dev": true, "requires": { - "typechecker": "2.0.8" + "typechecker": "~2.0.1" }, "dependencies": { "typechecker": { @@ -3851,7 +3854,7 @@ "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", "requires": { - "checkpoint-store": "1.1.0" + "checkpoint-store": "^1.1.0" } }, "fast-csv": { @@ -3888,13 +3891,13 @@ "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", "dev": true, "requires": { - "core-js": "1.2.7", - "isomorphic-fetch": "2.2.1", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "promise": "7.3.1", - "setimmediate": "1.0.5", - "ua-parser-js": "0.7.18" + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" }, "dependencies": { "core-js": { @@ -3910,7 +3913,7 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "requires": { - "pend": "1.2.0" + "pend": "~1.2.0" } }, "fetch-ponyfill": { @@ -3918,7 +3921,7 @@ "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", "requires": { - "node-fetch": "1.7.3" + "node-fetch": "~1.7.1" } }, "figures": { @@ -3927,7 +3930,7 @@ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { - "escape-string-regexp": "1.0.5" + "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { @@ -3936,8 +3939,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "file-type": { @@ -3957,11 +3960,11 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" } }, "finalhandler": { @@ -3970,12 +3973,12 @@ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, "find-up": { @@ -3983,7 +3986,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "2.0.0" + "locate-path": "^2.0.0" } }, "flat-cache": { @@ -3992,10 +3995,10 @@ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, "for-each": { @@ -4003,7 +4006,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", "requires": { - "is-function": "1.0.1" + "is-function": "~1.0.0" } }, "for-in": { @@ -4017,7 +4020,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "foreach": { @@ -4035,9 +4038,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "asynckit": "0.4.0", + "asynckit": "^0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.18" + "mime-types": "^2.1.12" } }, "forwarded": { @@ -4050,7 +4053,7 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -4058,15 +4061,20 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" + }, "fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, "fs-promise": { @@ -4074,10 +4082,10 @@ "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", "requires": { - "any-promise": "1.3.0", - "fs-extra": "2.1.2", - "mz": "2.7.0", - "thenify-all": "1.6.0" + "any-promise": "^1.3.0", + "fs-extra": "^2.0.0", + "mz": "^2.6.0", + "thenify-all": "^1.6.0" }, "dependencies": { "fs-extra": { @@ -4085,8 +4093,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" } }, "jsonfile": { @@ -4094,7 +4102,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } } } @@ -4110,8 +4118,8 @@ "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", "optional": true, "requires": { - "nan": "2.9.2", - "node-pre-gyp": "0.6.39" + "nan": "^2.3.0", + "node-pre-gyp": "^0.6.39" }, "dependencies": { "abbrev": { @@ -4124,8 +4132,8 @@ "bundled": true, "optional": true, "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" } }, "ansi-regex": { @@ -4142,8 +4150,8 @@ "bundled": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "asn1": { @@ -4180,28 +4188,28 @@ "bundled": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "block-stream": { "version": "0.0.9", "bundled": true, "requires": { - "inherits": "2.0.3" + "inherits": "~2.0.0" } }, "boom": { "version": "2.10.1", "bundled": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "brace-expansion": { "version": "1.1.7", "bundled": true, "requires": { - "balanced-match": "0.4.2", + "balanced-match": "^0.4.1", "concat-map": "0.0.1" } }, @@ -4227,7 +4235,7 @@ "version": "1.0.5", "bundled": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "concat-map": { @@ -4246,7 +4254,7 @@ "version": "2.0.5", "bundled": true, "requires": { - "boom": "2.10.1" + "boom": "2.x.x" } }, "dashdash": { @@ -4254,7 +4262,7 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -4296,7 +4304,7 @@ "bundled": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "extend": { @@ -4331,10 +4339,10 @@ "version": "1.0.11", "bundled": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "fstream-ignore": { @@ -4342,9 +4350,9 @@ "bundled": true, "optional": true, "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" } }, "gauge": { @@ -4352,14 +4360,14 @@ "bundled": true, "optional": true, "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "getpass": { @@ -4367,7 +4375,7 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" }, "dependencies": { "assert-plus": { @@ -4381,12 +4389,12 @@ "version": "7.1.2", "bundled": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "graceful-fs": { @@ -4416,10 +4424,10 @@ "version": "3.1.3", "bundled": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "hoek": { @@ -4431,17 +4439,17 @@ "bundled": true, "optional": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { "version": "1.0.6", "bundled": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -4479,7 +4487,7 @@ "bundled": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "jsbn": { @@ -4497,7 +4505,7 @@ "bundled": true, "optional": true, "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stringify-safe": { @@ -4567,17 +4575,17 @@ "bundled": true, "optional": true, "requires": { - "detect-libc": "1.0.2", + "detect-libc": "^1.0.2", "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.0.2", + "rc": "^1.1.7", "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^2.2.1", + "tar-pack": "^3.4.0" } }, "nopt": { @@ -4585,8 +4593,8 @@ "bundled": true, "optional": true, "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npmlog": { @@ -4594,10 +4602,10 @@ "bundled": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -4618,7 +4626,7 @@ "version": "1.4.0", "bundled": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -4636,8 +4644,8 @@ "bundled": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -4668,10 +4676,10 @@ "bundled": true, "optional": true, "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -4685,13 +4693,13 @@ "version": "2.2.9", "bundled": true, "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" } }, "request": { @@ -4699,35 +4707,35 @@ "bundled": true, "optional": true, "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" } }, "rimraf": { "version": "2.6.1", "bundled": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -4753,7 +4761,7 @@ "version": "1.0.9", "bundled": true, "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" } }, "sshpk": { @@ -4761,15 +4769,15 @@ "bundled": true, "optional": true, "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jodid25519": "^1.0.0", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" }, "dependencies": { "assert-plus": { @@ -4783,16 +4791,16 @@ "version": "1.0.2", "bundled": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.0.1", "bundled": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "stringstream": { @@ -4804,7 +4812,7 @@ "version": "3.0.1", "bundled": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -4816,9 +4824,9 @@ "version": "2.2.1", "bundled": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-pack": { @@ -4826,14 +4834,14 @@ "bundled": true, "optional": true, "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" + "debug": "^2.2.0", + "fstream": "^1.0.10", + "fstream-ignore": "^1.0.5", + "once": "^1.3.3", + "readable-stream": "^2.1.4", + "rimraf": "^2.5.1", + "tar": "^2.2.1", + "uid-number": "^0.0.6" } }, "tough-cookie": { @@ -4841,7 +4849,7 @@ "bundled": true, "optional": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { @@ -4849,7 +4857,7 @@ "bundled": true, "optional": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -4884,7 +4892,7 @@ "bundled": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { @@ -4898,10 +4906,10 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.2.8" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "function-bind": { @@ -4920,7 +4928,7 @@ "integrity": "sha512-yXzteu4SIgUL31mnpm9j+x6dpHUw0p/nsRVkcySKq0w+1vDxH9jMErP1QhZAJuTVE6ni4nfvGSNkaQx5cD3jfg==", "dev": true, "requires": { - "source-map-support": "0.5.9" + "source-map-support": "^0.5.3" }, "dependencies": { "source-map": { @@ -4935,8 +4943,8 @@ "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", "dev": true, "requires": { - "buffer-from": "1.0.0", - "source-map": "0.6.1" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } } } @@ -4961,7 +4969,7 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -4969,12 +4977,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-base": { @@ -4983,8 +4991,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" } }, "glob-parent": { @@ -4993,7 +5001,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "^2.0.0" } }, "global": { @@ -5001,8 +5009,8 @@ "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", "requires": { - "min-document": "2.19.0", - "process": "0.5.2" + "min-document": "^2.19.0", + "process": "~0.5.1" } }, "globals": { @@ -5026,10 +5034,10 @@ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" }, "dependencies": { "source-map": { @@ -5038,7 +5046,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -5053,8 +5061,8 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "ajv": "^5.1.0", + "har-schema": "^2.0.0" } }, "has": { @@ -5062,7 +5070,7 @@ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.0.2" } }, "has-ansi": { @@ -5070,7 +5078,7 @@ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -5088,7 +5096,7 @@ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", "requires": { - "has-symbol-support-x": "1.4.2" + "has-symbol-support-x": "^1.4.1" } }, "has-value": { @@ -5096,9 +5104,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -5113,8 +5121,8 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "is-number": { @@ -5122,7 +5130,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -5130,7 +5138,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5140,7 +5148,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5150,7 +5158,7 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", "requires": { - "inherits": "2.0.3" + "inherits": "^2.0.1" } }, "hash.js": { @@ -5158,8 +5166,8 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" } }, "hawk": { @@ -5167,10 +5175,10 @@ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.1", - "sntp": "2.1.0" + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" } }, "hdkey": { @@ -5178,8 +5186,8 @@ "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", "requires": { - "coinstring": "2.3.0", - "secp256k1": "3.5.0" + "coinstring": "^2.0.0", + "secp256k1": "^3.0.1" } }, "he": { @@ -5193,9 +5201,9 @@ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { - "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, "hoek": { @@ -5208,8 +5216,8 @@ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "hosted-git-info": { @@ -5225,7 +5233,7 @@ "depd": "1.1.1", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": "1.4.0" + "statuses": ">= 1.3.1 < 2" }, "dependencies": { "depd": { @@ -5245,9 +5253,9 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "https-browserify": { @@ -5261,12 +5269,12 @@ "integrity": "sha1-LYzxwkciYCwgQdAbpq5eqlE4jw4=", "dev": true, "requires": { - "debug": "2.6.9", - "make-plural": "3.0.6", - "math-interval-parser": "1.1.0", - "messageformat": "0.3.1", - "mustache": "2.3.0", - "sprintf-js": "1.0.3" + "debug": "*", + "make-plural": "^3.0.3", + "math-interval-parser": "^1.1.0", + "messageformat": "^0.3.1", + "mustache": "*", + "sprintf-js": ">=1.0.3" } }, "iconv-lite": { @@ -5291,8 +5299,8 @@ "integrity": "sha1-2ln7hYl25KXkNwLM0fKC/byeV1Y=", "dev": true, "requires": { - "editions": "1.3.4", - "ignorepatterns": "1.1.0" + "editions": "^1.3.3", + "ignorepatterns": "^1.1.0" } }, "ignorepatterns": { @@ -5322,8 +5330,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -5341,7 +5349,7 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, "invert-kv": { @@ -5359,7 +5367,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-arrayish": { @@ -5372,7 +5380,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "requires": { - "binary-extensions": "1.11.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -5385,7 +5393,7 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-callable": { @@ -5398,7 +5406,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-date-object": { @@ -5411,9 +5419,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -5435,7 +5443,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -5449,7 +5457,7 @@ "integrity": "sha1-JE4UDfdbscmjEG9BL/GC+1NKbWI=", "dev": true, "requires": { - "extended": "0.0.6" + "extended": "~0.0.3" } }, "is-extglob": { @@ -5463,7 +5471,7 @@ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fn": { @@ -5487,7 +5495,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" } }, "is-hex-prefixed": { @@ -5501,7 +5509,7 @@ "integrity": "sha1-n69ltvttskt/XAYoR16nH5iEAeI=", "dev": true, "requires": { - "define-properties": "1.1.2" + "define-properties": "^1.1.1" } }, "is-natural-number": { @@ -5515,7 +5523,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-obj": { @@ -5534,7 +5542,7 @@ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", "requires": { - "is-number": "4.0.0" + "is-number": "^4.0.0" }, "dependencies": { "is-number": { @@ -5556,7 +5564,7 @@ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { - "is-path-inside": "1.0.1" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { @@ -5565,7 +5573,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-obj": { @@ -5578,7 +5586,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -5611,7 +5619,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "requires": { - "has": "1.0.1" + "has": "^1.0.1" } }, "is-resolvable": { @@ -5675,8 +5683,8 @@ "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "dev": true, "requires": { - "node-fetch": "1.7.3", - "whatwg-fetch": "2.0.3" + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" } }, "isstream": { @@ -5690,20 +5698,20 @@ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, "requires": { - "abbrev": "1.0.9", - "async": "1.5.2", - "escodegen": "1.8.1", - "esprima": "2.7.3", - "glob": "5.0.15", - "handlebars": "4.0.11", - "js-yaml": "3.11.0", - "mkdirp": "0.5.1", - "nopt": "3.0.6", - "once": "1.4.0", - "resolve": "1.1.7", - "supports-color": "3.2.3", - "which": "1.3.0", - "wordwrap": "1.0.0" + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" }, "dependencies": { "esprima": { @@ -5718,11 +5726,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-flag": { @@ -5743,7 +5751,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } @@ -5753,8 +5761,8 @@ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", "requires": { - "has-to-string-tag-x": "1.4.1", - "is-object": "1.0.1" + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" } }, "js-sha3": { @@ -5778,8 +5786,8 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "requires": { - "argparse": "1.0.10", - "esprima": "4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "jsbn": { @@ -5803,11 +5811,11 @@ "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.6.1.tgz", "integrity": "sha512-xYuD9M1pcld5OKPzVAoEG5MKtnR8iKMyNzRpeS3/mCJ7dcAcS67vqfOmYLoaIQfVRU5uClThbjri3VFR0vEwYg==", "requires": { - "async": "2.6.0", - "babel-preset-env": "1.6.1", - "babelify": "7.3.0", - "json-rpc-error": "2.0.0", - "promise-to-callback": "1.0.0" + "async": "^2.0.1", + "babel-preset-env": "^1.3.2", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0" }, "dependencies": { "async": { @@ -5815,7 +5823,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } } } @@ -5825,7 +5833,7 @@ "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", "requires": { - "inherits": "2.0.3" + "inherits": "^2.0.1" } }, "json-rpc-random-id": { @@ -5848,7 +5856,7 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, "json-stable-stringify-without-jsonify": { @@ -5882,7 +5890,7 @@ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "jsonify": { @@ -5906,10 +5914,10 @@ "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", "requires": { - "bindings": "1.3.0", - "inherits": "2.0.3", - "nan": "2.9.2", - "safe-buffer": "5.1.1" + "bindings": "^1.2.1", + "inherits": "^2.0.3", + "nan": "^2.2.1", + "safe-buffer": "^5.1.0" } }, "keccakjs": { @@ -5917,8 +5925,8 @@ "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", "requires": { - "browserify-sha3": "0.0.1", - "sha3": "1.2.0" + "browserify-sha3": "^0.0.1", + "sha3": "^1.1.0" } }, "kind-of": { @@ -5926,7 +5934,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "klaw": { @@ -5934,7 +5942,7 @@ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.9" } }, "lazy-cache": { @@ -5947,7 +5955,7 @@ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "lcov-parse": { @@ -5965,7 +5973,7 @@ "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", "requires": { - "errno": "0.1.7" + "errno": "~0.1.1" } }, "level-iterator-stream": { @@ -5973,10 +5981,10 @@ "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", "requires": { - "inherits": "2.0.3", - "level-errors": "1.0.5", - "readable-stream": "1.1.14", - "xtend": "4.0.1" + "inherits": "^2.0.1", + "level-errors": "^1.0.3", + "readable-stream": "^1.0.33", + "xtend": "^4.0.0" }, "dependencies": { "isarray": { @@ -5989,10 +5997,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -6007,8 +6015,8 @@ "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", "requires": { - "readable-stream": "1.0.34", - "xtend": "2.1.2" + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" }, "dependencies": { "isarray": { @@ -6021,10 +6029,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -6037,7 +6045,7 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", "requires": { - "object-keys": "0.4.0" + "object-keys": "~0.4.0" } } } @@ -6047,13 +6055,13 @@ "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", "requires": { - "deferred-leveldown": "1.2.2", - "level-codec": "7.0.1", - "level-errors": "1.0.5", - "level-iterator-stream": "1.3.1", - "prr": "1.0.1", - "semver": "5.4.1", - "xtend": "4.0.1" + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" }, "dependencies": { "semver": { @@ -6069,8 +6077,8 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "loader-runner": { @@ -6083,9 +6091,9 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" } }, "locate-path": { @@ -6093,8 +6101,8 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { @@ -6128,7 +6136,7 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "requires": { - "js-tokens": "3.0.2" + "js-tokens": "^3.0.0" } }, "lowercase-keys": { @@ -6141,8 +6149,8 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "lru-queue": { @@ -6151,7 +6159,7 @@ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", "dev": true, "requires": { - "es5-ext": "0.10.39" + "es5-ext": "~0.10.2" } }, "ltgt": { @@ -6164,7 +6172,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "make-plural": { @@ -6173,7 +6181,7 @@ "integrity": "sha1-IDOgO6wpC487uRJY9lud9+iwHKc=", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" }, "dependencies": { "minimist": { @@ -6195,7 +6203,7 @@ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "math-interval-parser": { @@ -6204,7 +6212,7 @@ "integrity": "sha1-2+2lsGsySZc8bfYXD94jhvCv2JM=", "dev": true, "requires": { - "xregexp": "2.0.0" + "xregexp": "^2.0.0" } }, "md5.js": { @@ -6212,8 +6220,8 @@ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" }, "dependencies": { "hash-base": { @@ -6221,8 +6229,8 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } } } @@ -6237,7 +6245,7 @@ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "memdown": { @@ -6245,12 +6253,12 @@ "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", "requires": { - "abstract-leveldown": "2.7.2", - "functional-red-black-tree": "1.0.1", - "immediate": "3.2.3", - "inherits": "2.0.3", - "ltgt": "2.2.0", - "safe-buffer": "5.1.1" + "abstract-leveldown": "~2.7.1", + "functional-red-black-tree": "^1.0.1", + "immediate": "^3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.1.1" }, "dependencies": { "abstract-leveldown": { @@ -6258,7 +6266,7 @@ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", "requires": { - "xtend": "4.0.1" + "xtend": "~4.0.0" } } } @@ -6269,14 +6277,14 @@ "integrity": "sha512-sprBu6nwxBWBvBOh5v2jcsGqiGLlL2xr2dLub3vR8dnE8YB17omwtm/0NSHl8jjNbcsJd5GMWJAnTSVe/O0Wfg==", "dev": true, "requires": { - "d": "1.0.0", - "es5-ext": "0.10.39", - "es6-weak-map": "2.0.2", - "event-emitter": "0.3.5", - "is-promise": "2.1.0", - "lru-queue": "0.1.0", - "next-tick": "1.0.0", - "timers-ext": "0.1.3" + "d": "1", + "es5-ext": "^0.10.30", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.2" } }, "memory-fs": { @@ -6284,8 +6292,8 @@ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.5" + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } }, "memorystream": { @@ -6303,14 +6311,14 @@ "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", "requires": { - "async": "1.5.2", - "ethereumjs-util": "5.1.5", + "async": "^1.4.2", + "ethereumjs-util": "^5.0.0", "level-ws": "0.0.0", - "levelup": "1.3.9", - "memdown": "1.4.1", - "readable-stream": "2.3.5", - "rlp": "2.0.0", - "semaphore": "1.1.0" + "levelup": "^1.2.1", + "memdown": "^1.0.0", + "readable-stream": "^2.0.0", + "rlp": "^2.0.0", + "semaphore": ">=1.0.1" }, "dependencies": { "ethereumjs-util": { @@ -6318,13 +6326,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } } } @@ -6335,11 +6343,11 @@ "integrity": "sha1-5Y//gkXps5cXmeW0PbWLPpQX9aI=", "dev": true, "requires": { - "async": "1.5.2", - "glob": "6.0.4", - "make-plural": "3.0.6", - "nopt": "3.0.6", - "watchr": "2.4.13" + "async": "~1.5.2", + "glob": "~6.0.4", + "make-plural": "~3.0.3", + "nopt": "~3.0.6", + "watchr": "~2.4.13" }, "dependencies": { "glob": { @@ -6348,11 +6356,11 @@ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "dev": true, "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } } } @@ -6368,19 +6376,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" } }, "miller-rabin": { @@ -6388,8 +6396,8 @@ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "requires": { - "bn.js": "4.11.6", - "brorand": "1.1.0" + "bn.js": "^4.0.0", + "brorand": "^1.0.1" } }, "mime": { @@ -6407,7 +6415,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "requires": { - "mime-db": "1.33.0" + "mime-db": "~1.33.0" } }, "mimic-fn": { @@ -6425,7 +6433,7 @@ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", "requires": { - "dom-walk": "0.1.1" + "dom-walk": "^0.1.0" } }, "minimalistic-assert": { @@ -6443,7 +6451,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -6456,8 +6464,8 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -6465,7 +6473,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -6483,7 +6491,7 @@ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", "requires": { - "mkdirp": "0.5.1" + "mkdirp": "*" } }, "mocha": { @@ -6543,7 +6551,7 @@ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } } } @@ -6565,7 +6573,7 @@ "integrity": "sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A==", "dev": true, "requires": { - "moment": "2.22.2" + "moment": ">= 2.9.0" } }, "mout": { @@ -6584,8 +6592,8 @@ "integrity": "sha512-HwJGEKPCpLlNlgGQA56CYh/Wsqa+c4JAq8+mheIgw7OK5T4QvNJqgp6TH8gZ4q4l1aiWeNat/H/MrFXmTuoFfQ==", "dev": true, "requires": { - "bs58": "4.0.1", - "varint": "5.0.0" + "bs58": "^4.0.1", + "varint": "^5.0.0" }, "dependencies": { "base-x": { @@ -6594,7 +6602,7 @@ "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "bs58": { @@ -6603,7 +6611,7 @@ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dev": true, "requires": { - "base-x": "3.0.4" + "base-x": "^3.0.2" } } } @@ -6625,9 +6633,9 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "requires": { - "any-promise": "1.3.0", - "object-assign": "4.1.1", - "thenify-all": "1.6.0" + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" } }, "nan": { @@ -6645,18 +6653,18 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-odd": "2.0.0", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-odd": "^2.0.0", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "arr-diff": { @@ -6710,8 +6718,8 @@ "integrity": "sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw==", "dev": true, "requires": { - "clone": "2.1.1", - "lodash": "4.17.5" + "clone": "2.x", + "lodash": "4.x" }, "dependencies": { "clone": { @@ -6727,8 +6735,8 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" + "encoding": "^0.1.11", + "is-stream": "^1.0.1" } }, "node-libs-browser": { @@ -6736,28 +6744,28 @@ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", "requires": { - "assert": "1.4.1", - "browserify-zlib": "0.2.0", - "buffer": "4.9.1", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "domain-browser": "1.2.0", - "events": "1.1.1", - "https-browserify": "1.0.0", - "os-browserify": "0.3.0", + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "readable-stream": "2.3.5", - "stream-browserify": "2.0.1", - "stream-http": "2.8.2", - "string_decoder": "1.0.3", - "timers-browserify": "2.0.10", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", + "url": "^0.11.0", + "util": "^0.10.3", "vm-browserify": "0.0.4" }, "dependencies": { @@ -6766,9 +6774,9 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.10", - "isarray": "1.0.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "process": { @@ -6784,9 +6792,9 @@ "integrity": "sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A==", "dev": true, "requires": { - "cron-parser": "2.5.0", + "cron-parser": "^2.4.0", "long-timeout": "0.1.1", - "sorted-array-functions": "1.2.0" + "sorted-array-functions": "^1.0.0" } }, "nopt": { @@ -6795,7 +6803,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1.0.9" + "abbrev": "1" } }, "normalize-package-data": { @@ -6803,10 +6811,10 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "requires": { - "hosted-git-info": "2.6.0", - "is-builtin-module": "1.0.0", - "semver": "5.5.0", - "validate-npm-package-license": "3.0.3" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { @@ -6814,7 +6822,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } }, "npm-run-path": { @@ -6822,7 +6830,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "number-is-nan": { @@ -6854,9 +6862,9 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -6864,7 +6872,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -6875,9 +6883,9 @@ "integrity": "sha1-hP0j9WsVWCrrPoiwXLVdJDLWijM=", "dev": true, "requires": { - "array-extended": "0.0.11", - "extended": "0.0.6", - "is-extended": "0.0.10" + "array-extended": "~0.0.4", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "object-inspect": { @@ -6895,7 +6903,7 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -6911,8 +6919,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "object.pick": { @@ -6920,7 +6928,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -6935,7 +6943,7 @@ "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", "requires": { - "http-https": "1.0.0" + "http-https": "^1.0.0" } }, "on-finished": { @@ -6951,7 +6959,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -6960,7 +6968,7 @@ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "openzeppelin-solidity": { @@ -6974,8 +6982,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" }, "dependencies": { "wordwrap": { @@ -6992,12 +7000,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "original-require": { @@ -7021,9 +7029,9 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" } }, "os-tmpdir": { @@ -7041,7 +7049,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "requires": { - "p-try": "1.0.0" + "p-try": "^1.0.0" } }, "p-locate": { @@ -7049,7 +7057,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "1.2.0" + "p-limit": "^1.1.0" } }, "p-try": { @@ -7067,11 +7075,11 @@ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "requires": { - "asn1.js": "4.10.1", - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.14" + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" } }, "parse-glob": { @@ -7080,10 +7088,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-headers": { @@ -7091,7 +7099,7 @@ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", "requires": { - "for-each": "0.3.2", + "for-each": "^0.3.2", "trim": "0.0.1" } }, @@ -7151,11 +7159,11 @@ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "pegjs": { @@ -7189,7 +7197,7 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pkg-dir": { @@ -7198,7 +7206,7 @@ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { - "find-up": "1.1.2" + "find-up": "^1.0.0" }, "dependencies": { "find-up": { @@ -7207,8 +7215,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "path-exists": { @@ -7217,7 +7225,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } } } @@ -7278,7 +7286,7 @@ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, "requires": { - "asap": "2.0.6" + "asap": "~2.0.3" } }, "promise-to-callback": { @@ -7286,8 +7294,8 @@ "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", "requires": { - "is-fn": "1.0.0", - "set-immediate-shim": "1.0.1" + "is-fn": "^1.0.0", + "set-immediate-shim": "^1.0.1" } }, "prop-types": { @@ -7296,8 +7304,8 @@ "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "dev": true, "requires": { - "loose-envify": "1.3.1", - "object-assign": "4.1.1" + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, "proxy-addr": { @@ -7305,7 +7313,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.6.0" } }, @@ -7324,11 +7332,11 @@ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", "requires": { - "bn.js": "4.11.6", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" } }, "punycode": { @@ -7346,9 +7354,9 @@ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.0.tgz", "integrity": "sha512-F3DkxxlY0AqD/rwe4YAwjRE2HjOkKW7TxsuteyrS/Jbwrxw887PqYBL4sWUJ9D/V1hmFns0SCD6FDyvlwo9RCQ==", "requires": { - "decode-uri-component": "0.2.0", - "object-assign": "4.1.1", - "strict-uri-encode": "1.1.0" + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" } }, "querystring": { @@ -7367,8 +7375,8 @@ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "is-number": { @@ -7377,7 +7385,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -7386,7 +7394,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -7397,7 +7405,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -7407,7 +7415,7 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.1.0" } }, "randomfill": { @@ -7415,8 +7423,8 @@ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "requires": { - "randombytes": "2.0.6", - "safe-buffer": "5.1.1" + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" } }, "randomhex": { @@ -7446,10 +7454,10 @@ "integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==", "dev": true, "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" } }, "react-dom": { @@ -7458,10 +7466,10 @@ "integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==", "dev": true, "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" } }, "readable-stream": { @@ -7469,13 +7477,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -7483,10 +7491,10 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.5", - "set-immediate-shim": "1.0.1" + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" } }, "readline-sync": { @@ -7499,7 +7507,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "requires": { - "resolve": "1.5.0" + "resolve": "^1.1.6" } }, "regenerate": { @@ -7517,9 +7525,9 @@ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "private": "0.1.8" + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" } }, "regex-cache": { @@ -7528,7 +7536,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "0.1.3" + "is-equal-shallow": "^0.1.3" } }, "regex-not": { @@ -7536,8 +7544,8 @@ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "regexpp": { @@ -7551,9 +7559,9 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "requires": { - "regenerate": "1.3.3", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "regjsgen": { @@ -7566,7 +7574,7 @@ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } }, "remove-trailing-separator": { @@ -7589,7 +7597,7 @@ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "req-cwd": { @@ -7598,7 +7606,7 @@ "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", "dev": true, "requires": { - "req-from": "1.0.1" + "req-from": "^1.0.1" } }, "req-from": { @@ -7607,7 +7615,7 @@ "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", "dev": true, "requires": { - "resolve-from": "2.0.0" + "resolve-from": "^2.0.0" } }, "request": { @@ -7615,28 +7623,28 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" } }, "require-directory": { @@ -7660,8 +7668,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" }, "dependencies": { "resolve-from": { @@ -7677,7 +7685,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, "resolve-from": { @@ -7697,8 +7705,8 @@ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, "resumer": { @@ -7706,7 +7714,7 @@ "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", "requires": { - "through": "2.3.8" + "through": "~2.3.4" } }, "ret": { @@ -7719,7 +7727,7 @@ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "requires": { - "align-text": "0.1.4" + "align-text": "^0.1.1" } }, "rimraf": { @@ -7732,8 +7740,8 @@ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", "requires": { - "hash-base": "2.0.2", - "inherits": "2.0.3" + "hash-base": "^2.0.0", + "inherits": "^2.0.1" } }, "rlp": { @@ -7747,7 +7755,7 @@ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { - "is-promise": "2.1.0" + "is-promise": "^2.1.0" } }, "rustbn.js": { @@ -7767,7 +7775,7 @@ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "dev": true, "requires": { - "rx-lite": "4.0.8" + "rx-lite": "*" } }, "safe": { @@ -7786,7 +7794,7 @@ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safefs": { @@ -7795,7 +7803,7 @@ "integrity": "sha1-gXDBRE1wOOCMrqBaN0+uL6NJ4Vw=", "dev": true, "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "*" } }, "scandirectory": { @@ -7804,9 +7812,9 @@ "integrity": "sha1-bOA/VKCQtmjjy+2/IO354xBZPnI=", "dev": true, "requires": { - "ignorefs": "1.2.0", - "safefs": "3.2.2", - "taskgroup": "4.3.1" + "ignorefs": "^1.0.0", + "safefs": "^3.1.2", + "taskgroup": "^4.0.5" } }, "scrypt": { @@ -7814,7 +7822,7 @@ "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", "requires": { - "nan": "2.9.2" + "nan": "^2.0.8" } }, "scrypt-async": { @@ -7833,8 +7841,8 @@ "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", "requires": { - "scrypt": "6.0.3", - "scryptsy": "1.2.1" + "scrypt": "^6.0.2", + "scryptsy": "^1.2.1" } }, "scryptsy": { @@ -7842,7 +7850,7 @@ "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", "requires": { - "pbkdf2": "3.0.14" + "pbkdf2": "^3.0.3" } }, "secp256k1": { @@ -7850,14 +7858,14 @@ "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", "requires": { - "bindings": "1.3.0", - "bip66": "1.1.5", - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "drbg.js": "1.0.1", - "elliptic": "6.4.0", - "nan": "2.9.2", - "safe-buffer": "5.1.1" + "bindings": "^1.2.1", + "bip66": "^1.1.3", + "bn.js": "^4.11.3", + "create-hash": "^1.1.2", + "drbg.js": "^1.0.1", + "elliptic": "^6.2.3", + "nan": "^2.2.1", + "safe-buffer": "^5.1.0" } }, "seek-bzip": { @@ -7865,7 +7873,7 @@ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", "requires": { - "commander": "2.8.1" + "commander": "~2.8.1" }, "dependencies": { "commander": { @@ -7873,7 +7881,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "requires": { - "graceful-readlink": "1.0.1" + "graceful-readlink": ">= 1.0.0" } } } @@ -7894,18 +7902,18 @@ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.2", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" } }, "serve-static": { @@ -7913,9 +7921,9 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, @@ -7924,11 +7932,11 @@ "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", "requires": { - "body-parser": "1.18.2", - "cors": "2.8.4", - "express": "4.16.3", - "request": "2.85.0", - "xhr": "2.4.1" + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" } }, "set-blocking": { @@ -7946,10 +7954,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -7957,7 +7965,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -7977,8 +7985,8 @@ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "sha3": { @@ -7986,7 +7994,7 @@ "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.0.tgz", "integrity": "sha1-aYnxtwpJhwWHajc+LGKs6WqpOZo=", "requires": { - "nan": "2.9.2" + "nan": "^2.0.5" } }, "shebang-command": { @@ -7994,7 +8002,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -8007,9 +8015,9 @@ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", "requires": { - "glob": "7.1.2", - "interpret": "1.1.0", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "signal-exit": { @@ -8027,9 +8035,9 @@ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz", "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==", "requires": { - "decompress-response": "3.3.0", - "once": "1.4.0", - "simple-concat": "1.0.0" + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, "slash": { @@ -8042,14 +8050,14 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.0" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -8057,7 +8065,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -8065,7 +8073,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -8075,9 +8083,9 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -8085,7 +8093,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -8093,7 +8101,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -8101,7 +8109,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -8109,9 +8117,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -8131,7 +8139,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" } }, "sntp": { @@ -8139,7 +8147,7 @@ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "sol-digger": { @@ -8160,12 +8168,12 @@ "integrity": "sha512-12Z84jxeb5VFlQOGS38HOiTrHYohU07oQ5wHOcFJmcRRbaL5kWN7IcldMO1QdW8kONyKdj0xhukzLlN5m5ix4w==", "dev": true, "requires": { - "bluebird": "3.5.1", - "cli-color": "1.2.0", - "commander": "2.14.1", - "debug": "3.1.0", - "fs-extra": "4.0.3", - "glob": "7.1.2" + "bluebird": "^3.5.0", + "cli-color": "^1.2.0", + "commander": "^2.11.0", + "debug": "^3.0.1", + "fs-extra": "^4.0.2", + "glob": "^7.1.2" }, "dependencies": { "debug": { @@ -8184,11 +8192,11 @@ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", "requires": { - "fs-extra": "0.30.0", - "memorystream": "0.3.1", - "require-from-string": "1.2.1", - "semver": "5.5.0", - "yargs": "4.8.1" + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" }, "dependencies": { "camelcase": { @@ -8201,9 +8209,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, "find-up": { @@ -8211,8 +8219,8 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "fs-extra": { @@ -8220,11 +8228,11 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.2.8" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } }, "is-fullwidth-code-point": { @@ -8232,7 +8240,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "jsonfile": { @@ -8240,7 +8248,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "load-json-file": { @@ -8248,11 +8256,11 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "os-locale": { @@ -8260,7 +8268,7 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { - "lcid": "1.0.0" + "lcid": "^1.0.0" } }, "parse-json": { @@ -8268,7 +8276,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-exists": { @@ -8276,7 +8284,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-type": { @@ -8284,9 +8292,9 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -8299,9 +8307,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -8309,8 +8317,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "string-width": { @@ -8318,9 +8326,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "which-module": { @@ -8333,20 +8341,20 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "requires": { - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "lodash.assign": "4.2.0", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", - "window-size": "0.2.0", - "y18n": "3.2.1", - "yargs-parser": "2.4.1" + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" } }, "yargs-parser": { @@ -8354,8 +8362,8 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "requires": { - "camelcase": "3.0.0", - "lodash.assign": "4.2.0" + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" } } } @@ -8366,20 +8374,21 @@ "integrity": "sha512-qikdsSi6+9XbfvwA0aI7HUVpF9fIFNqRWTw23M89GMDY+b6Gj0wWU9IngJS0fimoZIAdEp3bfChxvpfVcrUesg==", "dev": true, "requires": { - "death": "1.1.0", + "death": "^1.1.0", "ethereumjs-testrpc-sc": "6.1.6", - "istanbul": "0.4.5", - "keccakjs": "0.2.1", - "req-cwd": "1.0.1", - "shelljs": "0.7.8", - "sol-explore": "1.6.2", + "istanbul": "^0.4.5", + "keccakjs": "^0.2.1", + "req-cwd": "^1.0.1", + "shelljs": "^0.7.4", + "sol-explore": "^1.6.2", "solidity-parser-sc": "0.4.11", - "tree-kill": "1.2.0", - "web3": "0.18.4" + "tree-kill": "^1.2.0", + "web3": "^0.18.4" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "dev": true }, "shelljs": { @@ -8388,9 +8397,9 @@ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true, "requires": { - "glob": "7.1.2", - "interpret": "1.1.0", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" } }, "sol-explore": { @@ -8406,10 +8415,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -8420,13 +8429,13 @@ "integrity": "sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g==", "dev": true, "requires": { - "commander": "2.14.1", - "lodash": "4.17.5", - "mocha": "5.2.0", - "mustache": "2.3.0", - "react": "16.4.2", - "react-dom": "16.4.2", - "shelljs": "0.8.2" + "commander": "^2.14.1", + "lodash": "^4.17.5", + "mocha": "^5.0.1", + "mustache": "^2.3.0", + "react": "^16.2.0", + "react-dom": "^16.2.0", + "shelljs": "^0.8.1" }, "dependencies": { "browser-stdout": { @@ -8485,9 +8494,9 @@ "integrity": "sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw==", "dev": true, "requires": { - "mocha": "4.1.0", - "pegjs": "0.10.0", - "yargs": "4.8.1" + "mocha": "^4.1.0", + "pegjs": "^0.10.0", + "yargs": "^4.6.0" }, "dependencies": { "camelcase": { @@ -8502,9 +8511,9 @@ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, "find-up": { @@ -8513,8 +8522,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "is-fullwidth-code-point": { @@ -8523,7 +8532,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "load-json-file": { @@ -8532,11 +8541,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "os-locale": { @@ -8545,7 +8554,7 @@ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { - "lcid": "1.0.0" + "lcid": "^1.0.0" } }, "parse-json": { @@ -8554,7 +8563,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-exists": { @@ -8563,7 +8572,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-type": { @@ -8572,9 +8581,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -8589,9 +8598,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -8600,8 +8609,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "string-width": { @@ -8610,9 +8619,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "which-module": { @@ -8627,20 +8636,20 @@ "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "dev": true, "requires": { - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "lodash.assign": "4.2.0", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", - "window-size": "0.2.0", - "y18n": "3.2.1", - "yargs-parser": "2.4.1" + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" } }, "yargs-parser": { @@ -8649,8 +8658,8 @@ "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "dev": true, "requires": { - "camelcase": "3.0.0", - "lodash.assign": "4.2.0" + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" } } } @@ -8661,17 +8670,17 @@ "integrity": "sha512-hCZr5cEK2H6LVC1Lr7IGPGJ8Bs4Ktif9cmwnk3BHpoZLIwTtrNE0LUtTRBxkO3/G0GGB4OdxnnJT1pbgsJ/2Uw==", "dev": true, "requires": { - "ajv": "5.5.2", - "chokidar": "1.7.0", - "colors": "1.2.1", - "commander": "2.14.1", - "js-string-escape": "1.0.1", - "lodash": "4.17.5", + "ajv": "^5.2.2", + "chokidar": "^1.6.0", + "colors": "^1.1.2", + "commander": "^2.9.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.14.2", "sol-digger": "0.0.2", "sol-explore": "1.6.1", "solium-plugin-security": "0.1.1", "solparse": "2.2.4", - "text-table": "0.2.0" + "text-table": "^0.2.0" } }, "solium-plugin-security": { @@ -8686,9 +8695,9 @@ "integrity": "sha512-Sdyk983juUaOITdTD9U5Yc+MaX8kz4pN3wFyCRILWXW3+Ff96PxY9RLBuZINYbBgCAXN1a+kThJfFMlaXG9R6A==", "dev": true, "requires": { - "mocha": "4.1.0", - "pegjs": "0.10.0", - "yargs": "10.1.2" + "mocha": "^4.0.1", + "pegjs": "^0.10.0", + "yargs": "^10.0.3" }, "dependencies": { "commander": { @@ -8748,7 +8757,7 @@ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } }, "yargs": { @@ -8757,18 +8766,18 @@ "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", "dev": true, "requires": { - "cliui": "4.0.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "8.1.0" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^8.1.0" } }, "yargs-parser": { @@ -8777,7 +8786,7 @@ "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } } } @@ -8803,11 +8812,11 @@ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "requires": { - "atob": "2.1.1", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-support": { @@ -8815,7 +8824,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "requires": { - "source-map": "0.5.7" + "source-map": "^0.5.6" } }, "source-map-url": { @@ -8828,8 +8837,8 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.0" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { @@ -8842,8 +8851,8 @@ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "requires": { - "spdx-exceptions": "2.1.0", - "spdx-license-ids": "3.0.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { @@ -8856,7 +8865,7 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "sprintf-js": { @@ -8869,14 +8878,14 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" } }, "stack-trace": { @@ -8890,8 +8899,8 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -8899,7 +8908,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -8920,8 +8929,8 @@ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.5" + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" } }, "stream-http": { @@ -8929,11 +8938,11 @@ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" }, "dependencies": { "readable-stream": { @@ -8941,13 +8950,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "string_decoder": { @@ -8955,7 +8964,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } } } @@ -8971,10 +8980,10 @@ "integrity": "sha1-dBlX3/SHsCcqee7FpE8jnubxfM0=", "dev": true, "requires": { - "array-extended": "0.0.11", - "date-extended": "0.0.6", - "extended": "0.0.6", - "is-extended": "0.0.10" + "array-extended": "~0.0.5", + "date-extended": "~0.0.3", + "extended": "~0.0.3", + "is-extended": "~0.0.3" } }, "string-width": { @@ -8982,8 +8991,8 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "dependencies": { "ansi-regex": { @@ -8996,7 +9005,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -9006,9 +9015,9 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.10.0", - "function-bind": "1.1.1" + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" } }, "string_decoder": { @@ -9016,7 +9025,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "stringstream": { @@ -9029,7 +9038,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -9037,7 +9046,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "strip-dirs": { @@ -9045,7 +9054,7 @@ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", "requires": { - "is-natural-number": "4.0.1" + "is-natural-number": "^4.0.1" } }, "strip-eof": { @@ -9072,7 +9081,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "swarm-js": { @@ -9080,19 +9089,19 @@ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", "requires": { - "bluebird": "3.5.1", - "buffer": "5.1.0", - "decompress": "4.2.0", - "eth-lib": "0.1.27", - "fs-extra": "2.1.2", - "fs-promise": "2.0.3", - "got": "7.1.0", - "mime-types": "2.1.18", - "mkdirp-promise": "5.0.1", - "mock-fs": "4.4.2", - "setimmediate": "1.0.5", - "tar.gz": "1.0.7", - "xhr-request-promise": "0.1.2" + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "decompress": "^4.0.0", + "eth-lib": "^0.1.26", + "fs-extra": "^2.1.2", + "fs-promise": "^2.0.0", + "got": "^7.1.0", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar.gz": "^1.0.5", + "xhr-request-promise": "^0.1.2" }, "dependencies": { "fs-extra": { @@ -9100,8 +9109,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0" } }, "got": { @@ -9109,20 +9118,20 @@ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", "requires": { - "decompress-response": "3.3.0", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-plain-obj": "1.1.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "isurl": "1.0.0", - "lowercase-keys": "1.0.0", - "p-cancelable": "0.3.0", - "p-timeout": "1.2.1", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "url-parse-lax": "1.0.0", - "url-to-options": "1.0.1" + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" } }, "jsonfile": { @@ -9130,7 +9139,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "p-cancelable": { @@ -9143,7 +9152,7 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", "requires": { - "p-finally": "1.0.0" + "p-finally": "^1.0.0" } }, "prepend-http": { @@ -9156,7 +9165,7 @@ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } } } @@ -9167,12 +9176,12 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "chalk": "2.3.2", - "lodash": "4.17.5", + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", "slice-ansi": "1.0.0", - "string-width": "2.1.1" + "string-width": "^2.1.1" }, "dependencies": { "ansi-styles": { @@ -9181,7 +9190,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -9190,9 +9199,9 @@ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "slice-ansi": { @@ -9201,7 +9210,7 @@ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0" + "is-fullwidth-code-point": "^2.0.0" } }, "supports-color": { @@ -9210,7 +9219,7 @@ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -9220,19 +9229,19 @@ "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.0.tgz", "integrity": "sha512-j0jO9BiScfqtPBb9QmPLL0qvxXMz98xjkMb7x8lKipFlJZwNJkqkWPou+NU4V6T9RnVh1kuSthLE8gLrN8bBfw==", "requires": { - "deep-equal": "1.0.1", - "defined": "1.0.0", - "for-each": "0.3.2", - "function-bind": "1.1.1", - "glob": "7.1.2", - "has": "1.0.1", - "inherits": "2.0.3", - "minimist": "1.2.0", - "object-inspect": "1.5.0", - "resolve": "1.5.0", - "resumer": "0.0.0", - "string.prototype.trim": "1.1.2", - "through": "2.3.8" + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.2", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.1", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.5.0", + "resolve": "~1.5.0", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" }, "dependencies": { "minimist": { @@ -9247,9 +9256,9 @@ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" } }, "tar-stream": { @@ -9257,10 +9266,10 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", "requires": { - "bl": "1.2.2", - "end-of-stream": "1.4.1", - "readable-stream": "2.3.5", - "xtend": "4.0.1" + "bl": "^1.0.0", + "end-of-stream": "^1.0.0", + "readable-stream": "^2.0.0", + "xtend": "^4.0.0" } }, "tar.gz": { @@ -9268,11 +9277,11 @@ "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", "requires": { - "bluebird": "2.11.0", - "commander": "2.14.1", - "fstream": "1.0.11", - "mout": "0.11.1", - "tar": "2.2.1" + "bluebird": "^2.9.34", + "commander": "^2.8.1", + "fstream": "^1.0.8", + "mout": "^0.11.0", + "tar": "^2.1.1" }, "dependencies": { "bluebird": { @@ -9288,8 +9297,8 @@ "integrity": "sha1-feGT/r12gnPEV3MElwJNUSwnkVo=", "dev": true, "requires": { - "ambi": "2.5.0", - "csextends": "1.2.0" + "ambi": "^2.2.0", + "csextends": "^1.0.3" } }, "text-table": { @@ -9303,7 +9312,7 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", "requires": { - "any-promise": "1.3.0" + "any-promise": "^1.0.0" } }, "thenify-all": { @@ -9311,7 +9320,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", "requires": { - "thenify": "3.3.0" + "thenify": ">= 3.1.0 < 4" } }, "through": { @@ -9329,7 +9338,7 @@ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "requires": { - "setimmediate": "1.0.5" + "setimmediate": "^1.0.4" } }, "timers-ext": { @@ -9338,8 +9347,8 @@ "integrity": "sha512-2iKErlS+NnEr0aQVQS91/mjsqCDO4OFl+5c5RDNtP+acQJTySvNSdbiSbmBD0t2RbErirF2Vq7x5YPQOSva77Q==", "dev": true, "requires": { - "es5-ext": "0.10.39", - "next-tick": "1.0.0" + "es5-ext": "~0.10.14", + "next-tick": "1" } }, "tingodb": { @@ -9348,10 +9357,10 @@ "integrity": "sha1-9jM2JZr336bJDf4lVqDfsNTu3lk=", "dev": true, "requires": { - "bson": "1.0.9", - "lodash": "4.17.5", - "safe": "0.4.6", - "safe-buffer": "5.1.1" + "bson": "^1.0.4", + "lodash": "^4.17.5", + "safe": "^0.4.5", + "safe-buffer": "^5.1.1" } }, "tmp": { @@ -9360,7 +9369,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.2" } }, "to-arraybuffer": { @@ -9378,7 +9387,7 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "to-regex": { @@ -9386,10 +9395,10 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -9397,8 +9406,8 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" }, "dependencies": { "is-number": { @@ -9406,7 +9415,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } } } @@ -9416,7 +9425,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tree-kill": { @@ -9441,7 +9450,7 @@ "integrity": "sha1-vydYaYi0/4RWPt+/MrR5QUCKdq0=", "dev": true, "requires": { - "mocha": "4.1.0", + "mocha": "^4.1.0", "original-require": "1.0.1", "solc": "0.4.24" } @@ -9457,14 +9466,15 @@ "integrity": "sha512-/1LCtJFf5Jvm5Rv88T0d/rZSKvaiW/yO1SHXLGJgKzLsiG1F/2spFs4HrI1mRxP00opfrYXloEmLtkVV/kcndQ==", "requires": { "ethjs-abi": "0.1.8", - "truffle-blockchain-utils": "0.0.4", - "truffle-contract-schema": "2.0.0", + "truffle-blockchain-utils": "^0.0.4", + "truffle-contract-schema": "^2.0.0", "truffle-error": "0.0.2", - "web3": "0.20.6" + "web3": "^0.20.1" }, "dependencies": { "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" }, "ethjs-abi": { "version": "0.1.8", @@ -9482,10 +9492,10 @@ "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -9495,9 +9505,9 @@ "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-2.0.0.tgz", "integrity": "sha512-nLlspmu1GKDaluWksBwitHi/7Z3IpRjmBYeO9N+T1nVJD2V4IWJaptCKP1NqnPiJA+FChB7+F7pI6Br51/FtXQ==", "requires": { - "ajv": "5.5.2", - "crypto-js": "3.1.9-1", - "debug": "3.1.0" + "ajv": "^5.1.1", + "crypto-js": "^3.1.9-1", + "debug": "^3.1.0" }, "dependencies": { "crypto-js": { @@ -9525,10 +9535,10 @@ "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.1.0.tgz", "integrity": "sha512-Vj04yr2d9qLRZspoHztbE/YQnVaoFb90JNZHtggRUm+JFm/NOiSJHLVI63+3mtUIuQ04EuKZ7Df8JQw0Ni7IeA==", "requires": { - "ethereumjs-tx": "1.3.4", - "ethereumjs-wallet": "0.6.0", - "web3": "0.20.6", - "web3-provider-engine": "13.6.6" + "ethereumjs-tx": "^1.3.3", + "ethereumjs-wallet": "^0.6.0", + "web3": "^0.20.5", + "web3-provider-engine": "^13.6.4" }, "dependencies": { "async": { @@ -9536,11 +9546,12 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", + "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" }, "clone": { "version": "2.1.2", @@ -9552,13 +9563,13 @@ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "web3": { @@ -9567,10 +9578,10 @@ "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", "requires": { "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } }, "web3-provider-engine": { @@ -9578,25 +9589,25 @@ "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.6.6.tgz", "integrity": "sha512-M9eztIxwCR2U7+d42RXdu3fBjvG/kcv7Ra8z2PHs912aHhAkMtNfvzhC8dboC7yKmj230eVHwouSXKizmSqC7Q==", "requires": { - "async": "2.6.0", - "clone": "2.1.2", - "eth-block-tracker": "2.3.0", - "eth-sig-util": "1.4.2", - "ethereumjs-block": "1.7.1", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "ethereumjs-vm": "2.3.3", - "fetch-ponyfill": "4.1.0", - "json-rpc-error": "2.0.0", - "json-stable-stringify": "1.0.1", - "promise-to-callback": "1.0.0", - "readable-stream": "2.3.5", - "request": "2.85.0", - "semaphore": "1.1.0", - "solc": "0.4.24", - "tape": "4.9.0", - "xhr": "2.4.1", - "xtend": "4.0.1" + "async": "^2.5.0", + "clone": "^2.0.0", + "eth-block-tracker": "^2.2.2", + "eth-sig-util": "^1.4.2", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.1.1", + "ethereumjs-vm": "^2.0.2", + "fetch-ponyfill": "^4.0.0", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "readable-stream": "^2.2.9", + "request": "^2.67.0", + "semaphore": "^1.0.3", + "solc": "^0.4.2", + "tape": "^4.4.0", + "xhr": "^2.2.0", + "xtend": "^4.0.1" } } } @@ -9607,13 +9618,14 @@ "integrity": "sha1-21nOb6HFWHZgERN1CalN/KjRQI4=", "dev": true, "requires": { - "ethereumjs-wallet": "0.6.0", - "web3": "0.18.4", - "web3-provider-engine": "8.6.1" + "ethereumjs-wallet": "^0.6.0", + "web3": "^0.18.2", + "web3-provider-engine": "^8.4.0" }, "dependencies": { "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", + "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", "dev": true }, "web3": { @@ -9623,10 +9635,10 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xhr2": "0.1.4", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xhr2": "*", + "xmlhttprequest": "*" } } } @@ -9641,7 +9653,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -9656,7 +9668,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "type-is": { @@ -9665,7 +9677,7 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.18" + "mime-types": "~2.1.18" } }, "typechecker": { @@ -9685,7 +9697,7 @@ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "requires": { - "is-typedarray": "1.0.0" + "is-typedarray": "^1.0.0" } }, "ua-parser-js": { @@ -9699,9 +9711,9 @@ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" }, "dependencies": { "camelcase": { @@ -9714,8 +9726,8 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", + "center-align": "^0.1.1", + "right-align": "^0.1.1", "wordwrap": "0.0.2" } }, @@ -9734,9 +9746,9 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", "window-size": "0.1.0" } } @@ -9753,9 +9765,9 @@ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", "requires": { - "source-map": "0.5.7", - "uglify-js": "2.8.29", - "webpack-sources": "1.1.0" + "source-map": "^0.5.6", + "uglify-js": "^2.8.29", + "webpack-sources": "^1.0.1" } }, "ultron": { @@ -9768,8 +9780,8 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", "requires": { - "buffer": "3.6.0", - "through": "2.3.8" + "buffer": "^3.0.1", + "through": "^2.3.6" }, "dependencies": { "base64-js": { @@ -9783,8 +9795,8 @@ "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", "requires": { "base64-js": "0.0.8", - "ieee754": "1.1.10", - "isarray": "1.0.0" + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } } } @@ -9794,10 +9806,10 @@ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { @@ -9805,7 +9817,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "set-value": { @@ -9813,10 +9825,10 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" } } } @@ -9843,8 +9855,8 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -9852,9 +9864,9 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -9889,7 +9901,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", "requires": { - "punycode": "2.1.0" + "punycode": "^2.1.0" }, "dependencies": { "punycode": { @@ -9935,7 +9947,7 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.2" }, "dependencies": { "kind-of": { @@ -9991,8 +10003,8 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "requires": { - "spdx-correct": "3.0.0", - "spdx-expression-parse": "3.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "varint": { @@ -10011,9 +10023,9 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "vm-browserify": { @@ -10029,9 +10041,9 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "requires": { - "chokidar": "2.0.3", - "graceful-fs": "4.1.11", - "neo-async": "2.5.0" + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" }, "dependencies": { "anymatch": { @@ -10039,8 +10051,8 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "arr-diff": { @@ -10058,16 +10070,16 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.2", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -10075,7 +10087,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -10085,18 +10097,18 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.1.3", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0", - "upath": "1.0.5" + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.1.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.0" } }, "expand-brackets": { @@ -10104,13 +10116,13 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -10118,7 +10130,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -10126,7 +10138,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -10134,7 +10146,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -10142,7 +10154,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -10152,7 +10164,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -10160,7 +10172,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -10170,9 +10182,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } }, "kind-of": { @@ -10187,14 +10199,14 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -10202,7 +10214,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -10210,7 +10222,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -10220,10 +10232,10 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -10231,7 +10243,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -10241,8 +10253,8 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -10250,7 +10262,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -10260,7 +10272,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -10268,7 +10280,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -10276,9 +10288,9 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-extglob": { @@ -10291,7 +10303,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-number": { @@ -10299,7 +10311,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -10307,7 +10319,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -10327,19 +10339,19 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.9", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } @@ -10350,14 +10362,14 @@ "integrity": "sha1-10hHu01vkPYf4sdPn2hmKqDgdgE=", "dev": true, "requires": { - "eachr": "2.0.4", - "extendr": "2.1.0", - "extract-opts": "2.2.0", - "ignorefs": "1.2.0", - "safefs": "3.2.2", - "scandirectory": "2.5.0", - "taskgroup": "4.3.1", - "typechecker": "2.1.0" + "eachr": "^2.0.2", + "extendr": "^2.1.0", + "extract-opts": "^2.2.0", + "ignorefs": "^1.0.0", + "safefs": "^3.1.2", + "scandirectory": "^2.5.0", + "taskgroup": "^4.2.0", + "typechecker": "^2.0.8" } }, "web3": { @@ -10389,20 +10401,20 @@ "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", "requires": { - "decompress-response": "3.3.0", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-plain-obj": "1.1.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "isurl": "1.0.0", - "lowercase-keys": "1.0.0", - "p-cancelable": "0.3.0", - "p-timeout": "1.2.1", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "url-parse-lax": "1.0.0", - "url-to-options": "1.0.1" + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" } }, "p-cancelable": { @@ -10415,7 +10427,7 @@ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", "requires": { - "p-finally": "1.0.0" + "p-finally": "^1.0.0" } }, "prepend-http": { @@ -10433,7 +10445,7 @@ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } } } @@ -10596,9 +10608,9 @@ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", "requires": { - "bn.js": "4.11.6", - "elliptic": "6.4.0", - "xhr-request-promise": "0.1.2" + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" } }, "underscore": { @@ -10672,20 +10684,20 @@ "integrity": "sha1-TYbhnjDKr5ffNRUR7A9gE25bMOs=", "dev": true, "requires": { - "async": "2.6.0", - "clone": "2.1.1", - "ethereumjs-block": "1.7.1", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "5.1.5", - "ethereumjs-vm": "2.3.3", - "isomorphic-fetch": "2.2.1", - "request": "2.85.0", - "semaphore": "1.1.0", - "solc": "0.4.24", - "tape": "4.9.0", - "web3": "0.16.0", - "xhr": "2.4.1", - "xtend": "4.0.1" + "async": "^2.1.2", + "clone": "^2.0.0", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.0.1", + "ethereumjs-vm": "^2.0.2", + "isomorphic-fetch": "^2.2.0", + "request": "^2.67.0", + "semaphore": "^1.0.3", + "solc": "^0.4.2", + "tape": "^4.4.0", + "web3": "^0.16.0", + "xhr": "^2.2.0", + "xtend": "^4.0.1" }, "dependencies": { "async": { @@ -10694,11 +10706,12 @@ "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "bignumber.js": { "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", + "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", "dev": true }, "clone": { @@ -10713,13 +10726,13 @@ "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", "dev": true, "requires": { - "bn.js": "4.11.6", - "create-hash": "1.1.3", - "ethjs-util": "0.1.4", - "keccak": "1.4.0", - "rlp": "2.0.0", - "safe-buffer": "5.1.1", - "secp256k1": "3.5.0" + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "ethjs-util": "^0.1.3", + "keccak": "^1.0.2", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1", + "secp256k1": "^3.0.1" } }, "web3": { @@ -10729,9 +10742,9 @@ "dev": true, "requires": { "bignumber.js": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "crypto-js": "3.1.8", - "utf8": "2.1.1", - "xmlhttprequest": "1.8.0" + "crypto-js": "^3.1.4", + "utf8": "^2.1.1", + "xmlhttprequest": "*" } } } @@ -10816,28 +10829,28 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz", "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", "requires": { - "acorn": "5.5.3", - "acorn-dynamic-import": "2.0.2", - "ajv": "6.5.0", - "ajv-keywords": "3.2.0", - "async": "2.6.0", - "enhanced-resolve": "3.4.1", - "escope": "3.6.0", - "interpret": "1.1.0", - "json-loader": "0.5.7", - "json5": "0.5.1", - "loader-runner": "2.3.0", - "loader-utils": "1.1.0", - "memory-fs": "0.4.1", - "mkdirp": "0.5.1", - "node-libs-browser": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.5.0", - "tapable": "0.2.8", - "uglifyjs-webpack-plugin": "0.4.6", - "watchpack": "1.6.0", - "webpack-sources": "1.1.0", - "yargs": "8.0.2" + "acorn": "^5.0.0", + "acorn-dynamic-import": "^2.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "async": "^2.1.2", + "enhanced-resolve": "^3.4.0", + "escope": "^3.6.0", + "interpret": "^1.0.0", + "json-loader": "^0.5.4", + "json5": "^0.5.1", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "mkdirp": "~0.5.0", + "node-libs-browser": "^2.0.0", + "source-map": "^0.5.3", + "supports-color": "^4.2.1", + "tapable": "^0.2.7", + "uglifyjs-webpack-plugin": "^0.4.6", + "watchpack": "^1.4.0", + "webpack-sources": "^1.0.1", + "yargs": "^8.0.2" }, "dependencies": { "ajv": { @@ -10845,10 +10858,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1", - "uri-js": "4.2.1" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0", + "uri-js": "^4.2.1" } }, "ajv-keywords": { @@ -10861,7 +10874,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "requires": { - "lodash": "4.17.5" + "lodash": "^4.14.0" } }, "cliui": { @@ -10869,9 +10882,9 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" }, "dependencies": { "string-width": { @@ -10879,9 +10892,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -10891,10 +10904,10 @@ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", "requires": { - "graceful-fs": "4.1.11", - "memory-fs": "0.4.1", - "object-assign": "4.1.1", - "tapable": "0.2.8" + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "object-assign": "^4.0.1", + "tapable": "^0.2.7" } }, "fast-deep-equal": { @@ -10912,7 +10925,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "load-json-file": { @@ -10920,10 +10933,10 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, "parse-json": { @@ -10931,7 +10944,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "path-type": { @@ -10939,7 +10952,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "requires": { - "pify": "2.3.0" + "pify": "^2.0.0" } }, "pify": { @@ -10952,9 +10965,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "read-pkg-up": { @@ -10962,8 +10975,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "strip-bom": { @@ -10976,7 +10989,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "requires": { - "has-flag": "2.0.0" + "has-flag": "^2.0.0" } }, "tapable": { @@ -10989,19 +11002,19 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", "requires": { - "camelcase": "4.1.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "read-pkg-up": "2.0.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "7.0.0" + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" } }, "yargs-parser": { @@ -11009,7 +11022,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } } } @@ -11019,8 +11032,8 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", "requires": { - "source-list-map": "2.0.0", - "source-map": "0.6.1" + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" }, "dependencies": { "source-map": { @@ -11032,11 +11045,12 @@ }, "websocket": { "version": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", + "from": "websocket@git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", "requires": { - "debug": "2.6.9", - "nan": "2.9.2", - "typedarray-to-buffer": "3.1.5", - "yaeti": "0.0.6" + "debug": "^2.2.0", + "nan": "^2.3.3", + "typedarray-to-buffer": "^3.1.2", + "yaeti": "^0.0.6" } }, "whatwg-fetch": { @@ -11050,7 +11064,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "which-module": { @@ -11069,12 +11083,12 @@ "integrity": "sha512-GYKuysPz2pxYAVJD2NPsDLP5Z79SDEzPm9/j4tCjkF/n89iBNGBMJcR+dMUqxgPNgoSs6fVygPi+Vl2oxIpBuw==", "dev": true, "requires": { - "async": "1.0.0", - "colors": "1.0.3", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "stack-trace": "0.0.10" + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" }, "dependencies": { "async": { @@ -11102,8 +11116,8 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" }, "dependencies": { "is-fullwidth-code-point": { @@ -11111,7 +11125,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "string-width": { @@ -11119,9 +11133,9 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -11137,7 +11151,7 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "ws": { @@ -11145,9 +11159,9 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "requires": { - "async-limiter": "1.0.0", - "safe-buffer": "5.1.1", - "ultron": "1.1.1" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } }, "xhr": { @@ -11155,10 +11169,10 @@ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.1.tgz", "integrity": "sha512-pAIU5vBr9Hiy5cpFIbPnwf0C18ZF86DBsZKrlsf87N5De/JbA6RJ83UP/cv+aljl4S40iRVMqP4pr4sF9Dnj0A==", "requires": { - "global": "4.3.2", - "is-function": "1.0.1", - "parse-headers": "2.0.1", - "xtend": "4.0.1" + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" } }, "xhr-request": { @@ -11166,13 +11180,13 @@ "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", "requires": { - "buffer-to-arraybuffer": "0.0.5", - "object-assign": "4.1.1", - "query-string": "5.1.0", - "simple-get": "2.7.0", - "timed-out": "4.0.1", - "url-set-query": "1.0.0", - "xhr": "2.4.1" + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" } }, "xhr-request-promise": { @@ -11180,7 +11194,7 @@ "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", "requires": { - "xhr-request": "1.1.0" + "xhr-request": "^1.0.1" } }, "xhr2": { @@ -11225,18 +11239,18 @@ "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", "dev": true, "requires": { - "cliui": "4.0.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "9.0.2" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" } }, "yargs-parser": { @@ -11245,7 +11259,7 @@ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } }, "yauzl": { @@ -11253,8 +11267,8 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" } } } diff --git a/package.json b/package.json index 3e06d880f..42cd36fd2 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "coveralls": "^3.0.1", "ethereumjs-testrpc": "^6.0.3", "ethers": "^3.0.15", + "fs": "0.0.1-security", "openzeppelin-solidity": "1.10.0", "readline-sync": "^1.4.9", "shelljs": "^0.8.2", diff --git a/truffle.js b/truffle.js index ac69a2338..63cd6779a 100644 --- a/truffle.js +++ b/truffle.js @@ -1,5 +1,7 @@ require('babel-register'); require('babel-polyfill'); +const fs = require('fs'); +const key = fs.readFileSync('./privKey').toString(); const HDWalletProvider = require("truffle-hdwallet-provider-privkey"); @@ -36,11 +38,11 @@ module.exports = { }, kovan: { provider: () => { - return new HDWalletProvider(require('fs').readFileSync('./privKey').toString(), "https://kovan.infura.io/") + return new HDWalletProvider(key, "https://kovan.infura.io/") }, network_id: '42', // Match any network id gas: 7900000, - gasPrice: 10000000000 + gasPrice: 5000000000 }, coverage: { host: "localhost", From 5ae5be34632bc9ae39ea01665a854d08ae630e6f Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 18:06:52 +0530 Subject: [PATCH 085/142] Coverage re enabled --- scripts/coverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/coverage.sh b/scripts/coverage.sh index c383e2022..e42ed6a84 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -2,4 +2,4 @@ rm -rf flat -TRAVIS_PULL_REQUEST=false scripts/test.sh \ No newline at end of file +TRAVIS_PULL_REQUEST=true scripts/test.sh \ No newline at end of file From 0761d5161395852c985f6d7a52483628ee0ddcb1 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 18:12:37 +0530 Subject: [PATCH 086/142] Migration fix --- migrations/2_deploy_contracts.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index fc242cc9b..2d107a25e 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -140,7 +140,7 @@ module.exports = function (deployer, network, accounts) { return deployer.deploy(ModuleRegistryProxy, {from: PolymathAccount}); }).then(() => { let bytesProxyMR = web3.eth.abi.encodeFunctionCall(functionSignatureProxyMR, [polymathRegistry.address, PolymathAccount]); - ModuleRegistryProxy.at(ModuleRegistryProxy.address).upgradeToAndCall("1.0.0", ModuleRegistry.address, bytesProxyMR, {from: PolymathAccount}); + return ModuleRegistryProxy.at(ModuleRegistryProxy.address).upgradeToAndCall("1.0.0", ModuleRegistry.address, bytesProxyMR, {from: PolymathAccount}); }).then(() => { moduleRegistry = ModuleRegistry.at(ModuleRegistryProxy.address); // Add module registry to polymath registry @@ -189,7 +189,7 @@ module.exports = function (deployer, network, accounts) { return deployer.deploy(SecurityTokenRegistryProxy, {from: PolymathAccount}); }).then(() => { let bytesProxy = web3.eth.abi.encodeFunctionCall(functionSignatureProxy, [PolymathRegistry.address, STFactory.address, initRegFee, initRegFee, PolyToken, PolymathAccount]); - SecurityTokenRegistryProxy.at(SecurityTokenRegistryProxy.address).upgradeToAndCall("1.0.0", SecurityTokenRegistry.address, bytesProxy, {from: PolymathAccount}); + return SecurityTokenRegistryProxy.at(SecurityTokenRegistryProxy.address).upgradeToAndCall("1.0.0", SecurityTokenRegistry.address, bytesProxy, {from: PolymathAccount}); }).then(() => { // Assign the address into the SecurityTokenRegistry key return polymathRegistry.changeAddress("SecurityTokenRegistry", SecurityTokenRegistryProxy.address, {from: PolymathAccount}); From 29fa0b55403a99d1c494880cb42c488b83a77d6c Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 5 Oct 2018 09:53:06 -0300 Subject: [PATCH 087/142] added mainnet oracle addresses --- migrations/2_deploy_contracts.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index fc242cc9b..0aa932233 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -66,9 +66,9 @@ module.exports = function (deployer, network, accounts) { web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/g5xfoQ0jFSE9S5LwM1Ei')) PolymathAccount = accounts[0] PolyToken = '0x9992eC3cF6A55b00978cdDF2b27BC6882d88D1eC' // Mainnet PolyToken Address - //POLYOracle = '0xfc2a00bb5b7e3b0b310ffb6de4fd1ea3835c9b27' // Poly Oracle Mainnet Address - //ETHOracle = '0x60055e9a93aae267da5a052e95846fa9469c0e7a' // ETH Oracle Mainnet Address - }if (network === 'coverage') { + POLYOracle = '0x52cb4616E191Ff664B0bff247469ce7b74579D1B' // Poly Oracle Mainnet Address + ETHOracle = '0x60055e9a93aae267da5a052e95846fa9469c0e7a' // ETH Oracle Mainnet Address + } if (network === 'coverage') { web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')) PolymathAccount = accounts[0] PolyToken = DevPolyToken.address // Development network polytoken address From 5b507fd78c758e564804008a2388dd96e2351fed Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 5 Oct 2018 09:55:00 -0300 Subject: [PATCH 088/142] adjusted mainnet migration gas price --- truffle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/truffle.js b/truffle.js index ac69a2338..adbd19de9 100644 --- a/truffle.js +++ b/truffle.js @@ -16,7 +16,7 @@ module.exports = { port: 8545, network_id: '1', // Match any network id gas: 7900000, - gasPrice: 50000000000 + gasPrice: 10000000000 }, ropsten: { // provider: new HDWalletProvider(privKey, "http://localhost:8545"), From ea909ad16b252535d2642cd10769094d45624d90 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 18:27:45 +0530 Subject: [PATCH 089/142] Hacky fix for nonce --- truffle.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/truffle.js b/truffle.js index 63cd6779a..a92ae5a62 100644 --- a/truffle.js +++ b/truffle.js @@ -1,6 +1,7 @@ require('babel-register'); require('babel-polyfill'); const fs = require('fs'); +const NonceTrackerSubprovider = require("web3-provider-engine/subproviders/nonce-tracker") const key = fs.readFileSync('./privKey').toString(); const HDWalletProvider = require("truffle-hdwallet-provider-privkey"); @@ -38,7 +39,11 @@ module.exports = { }, kovan: { provider: () => { - return new HDWalletProvider(key, "https://kovan.infura.io/") + let wallet = new HDWalletProvider(key, "https://kovan.infura.io/") + var nonceTracker = new NonceTrackerSubprovider() + wallet.engine._providers.unshift(nonceTracker) + nonceTracker.setEngine(wallet.engine) + return wallet }, network_id: '42', // Match any network id gas: 7900000, From f096c393393cd7a2963061d6d65b0ece5b04b8dc Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 5 Oct 2018 18:51:19 +0530 Subject: [PATCH 090/142] Update truffle.js --- truffle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/truffle.js b/truffle.js index a92ae5a62..9e9c64df2 100644 --- a/truffle.js +++ b/truffle.js @@ -2,7 +2,6 @@ require('babel-register'); require('babel-polyfill'); const fs = require('fs'); const NonceTrackerSubprovider = require("web3-provider-engine/subproviders/nonce-tracker") -const key = fs.readFileSync('./privKey').toString(); const HDWalletProvider = require("truffle-hdwallet-provider-privkey"); @@ -39,6 +38,7 @@ module.exports = { }, kovan: { provider: () => { + const key = fs.readFileSync('./privKey').toString(); let wallet = new HDWalletProvider(key, "https://kovan.infura.io/") var nonceTracker = new NonceTrackerSubprovider() wallet.engine._providers.unshift(nonceTracker) From 3b5f3a41fd74eef0b42f71e8b918c38a4290c5e2 Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 5 Oct 2018 20:00:24 +0530 Subject: [PATCH 091/142] remove redundant code --- test/e_erc20_dividends.js | 37 +++------------------------------ test/f_ether_dividends.js | 36 +++----------------------------- test/helpers/createInstances.js | 18 +++++++++++++++- 3 files changed, 23 insertions(+), 68 deletions(-) diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index c4fae1fc9..07af23bdb 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -2,7 +2,7 @@ import latestTime from "./helpers/latestTime"; import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployERC20DividendAndVerifyed } from "./helpers/createInstances"; const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); @@ -98,39 +98,8 @@ contract("ERC20DividendCheckpoint", accounts => { I_STRProxied ] = instances; - // STEP 6: Deploy the ERC20DividendCheckpoint - P_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new( - I_PolyToken.address, - web3.utils.toWei("500", "ether"), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_ERC20DividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ERC20DividendCheckpointFactory contract was not deployed" - ); - - // STEP 7: Deploy the ERC20DividendCheckpoint - I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - assert.notEqual( - I_ERC20DividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ERC20DividendCheckpointFactory contract was not deployed" - ); - - // STEP 8: Register the Modules with the ModuleRegistry contract - - // (A) : Register the ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - - // (B) : Register the Paid ERC20DividendCheckpointFactory - await I_MRProxied.registerModule(P_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); + [P_ERC20DividendCheckpointFactory] = await deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, web3.utils.toWei("500", "ether")); + [I_ERC20DividendCheckpointFactory] = await deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); // Printing all the contract addresses console.log(` diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index a8cccad0a..d4b9a3724 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -3,7 +3,7 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployEtherDividendAndVerifyed } from "./helpers/createInstances"; const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); @@ -98,38 +98,8 @@ contract("EtherDividendCheckpoint", accounts => { I_STRProxied ] = instances; - - // STEP 4: Deploy the ERC20DividendCheckpoint - P_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new( - I_PolyToken.address, - web3.utils.toWei("500", "ether"), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_EtherDividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ERC20DividendCheckpointFactory contract was not deployed" - ); - - // STEP 4: Deploy the EtherDividendCheckpoint - I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - assert.notEqual( - I_EtherDividendCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "EtherDividendCheckpointFactory contract was not deployed" - ); - - // (C) : Register the EtherDividendCheckpointFactory - await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid EtherDividendCheckpointFactory - await I_MRProxied.registerModule(P_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + [P_EtherDividendCheckpointFactory] = await deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, web3.utils.toWei("500", "ether")); + [P_EtherDividendCheckpointFactory] = await deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); // Printing all the contract addresses console.log(` diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index f6f797417..655c9ebc1 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -206,11 +206,27 @@ export async function deployERC20DividendAndVerifyed(account_polymath, I_MRProxi assert.notEqual( I_ERC20DividendCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" + "ERC20DividendCheckpointFactory contract was not deployed" ); await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); return new Array(I_ERC20DividendCheckpointFactory); +} + + +export async function deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { + I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); + + assert.notEqual( + I_EtherDividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "EtherDividendCheckpointFactory contract was not deployed" + ); + + await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); + + return new Array(I_EtherDividendCheckpointFactory); } \ No newline at end of file From 1d485d441ca99f7e0b11e053d135f57f402cc363 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 5 Oct 2018 14:31:22 -0300 Subject: [PATCH 092/142] fixed EternalStorage.sol indentation --- contracts/storage/EternalStorage.sol | 512 +++++++++++++-------------- 1 file changed, 256 insertions(+), 256 deletions(-) diff --git a/contracts/storage/EternalStorage.sol b/contracts/storage/EternalStorage.sol index d476b13bb..f75782dd3 100644 --- a/contracts/storage/EternalStorage.sol +++ b/contracts/storage/EternalStorage.sol @@ -3,261 +3,261 @@ pragma solidity ^0.4.24; contract EternalStorage { /// @notice Internal mappings use to store all kind on data into the contract - mapping(bytes32 => uint256) internal uintStorage; - mapping(bytes32 => string) internal stringStorage; - mapping(bytes32 => address) internal addressStorage; - mapping(bytes32 => bytes) internal bytesStorage; - mapping(bytes32 => bool) internal boolStorage; - mapping(bytes32 => int256) internal intStorage; - mapping(bytes32 => bytes32) internal bytes32Storage; - - /// @notice Internal mappings use to store the array of different data types - mapping(bytes32 => bytes32[]) internal bytes32ArrayStorage; - mapping(bytes32 => uint256[]) internal uintArrayStorage; - mapping(bytes32 => address[]) internal addressArrayStorage; - mapping(bytes32 => string[]) internal stringArrayStorage; - - ////////////////// - //// set functions - ////////////////// - /// @notice Set the key values using the Overloaded `set` functions - /// Ex- string version = "0.0.1"; replace to - /// set(keccak256(abi.encodePacked("version"), "0.0.1"); - /// same for the other variables as well some more example listed below - /// ex1 - address securityTokenAddress = 0x123; replace to - /// set(keccak256(abi.encodePacked("securityTokenAddress"), 0x123); - /// ex2 - bytes32 tokenDetails = "I am ST20"; replace to - /// set(keccak256(abi.encodePacked("tokenDetails"), "I am ST20"); - /// ex3 - mapping(string => address) ownedToken; - /// set(keccak256(abi.encodePacked("ownedToken", "Chris")), 0x123); - /// ex4 - mapping(string => uint) tokenIndex; - /// tokenIndex["TOKEN"] = 1; replace to set(keccak256(abi.encodePacked("tokenIndex", "TOKEN"), 1); - /// ex5 - mapping(string => SymbolDetails) registeredSymbols; where SymbolDetails is the structure having different type of values as - /// {uint256 date, string name, address owner} etc. - /// registeredSymbols["TOKEN"].name = "MyFristToken"; replace to set(keccak256(abi.encodePacked("registeredSymbols_name", "TOKEN"), "MyFirstToken"); - /// More generalized- set(keccak256(abi.encodePacked("registeredSymbols_", "keyname"), "value"); - - function set(bytes32 _key, uint256 _value) internal { - uintStorage[_key] = _value; - } - - function set(bytes32 _key, address _value) internal { - addressStorage[_key] = _value; - } - - function set(bytes32 _key, bool _value) internal { - boolStorage[_key] = _value; - } - - function set(bytes32 _key, bytes32 _value) internal { - bytes32Storage[_key] = _value; - } - - function set(bytes32 _key, string _value) internal { - stringStorage[_key] = _value; - } - - //////////////////// - /// get functions - //////////////////// - /// @notice Get function use to get the value of the singleton state variables - /// Ex1- string public version = "0.0.1"; - /// string _version = getString(keccak256(abi.encodePacked("version")); - /// Ex2 - assert(temp1 == temp2); replace to - /// assert(getUint(keccak256(abi.encodePacked(temp1)) == getUint(keccak256(abi.encodePacked(temp2)); - /// Ex3 - mapping(string => SymbolDetails) registeredSymbols; where SymbolDetails is the structure having different type of values as - /// {uint256 date, string name, address owner} etc. - /// string _name = getString(keccak256(abi.encodePacked("registeredSymbols_name", "TOKEN")); - - function getBool(bytes32 _key) internal view returns (bool) { - return boolStorage[_key]; - } - - function getUint(bytes32 _key) internal view returns (uint256) { - return uintStorage[_key]; - } - - function getAddress(bytes32 _key) internal view returns (address) { - return addressStorage[_key]; - } - - function getString(bytes32 _key) internal view returns (string) { - return stringStorage[_key]; - } - - function getBytes32(bytes32 _key) internal view returns (bytes32) { - return bytes32Storage[_key]; - } - - - //////////////////////////// - // deleteArray functions - //////////////////////////// - /// @notice Function use to delete the array element. - /// Ex1- mapping(address => bytes32[]) tokensOwnedByOwner; - /// For deleting the item from array developers needs to create a funtion for that similarly - /// in this case we have the helper function deleteArrayBytes32() which will do it for us - /// deleteArrayBytes32(keccak256(abi.encodePacked("tokensOwnedByOwner", 0x1), 3); -- it will delete the index 3 - - - //Deletes from mapping (bytes32 => array[]) at index _index - function deleteArrayAddress(bytes32 _key, uint256 _index) internal { - address[] storage array = addressArrayStorage[_key]; - require(_index < array.length, "Index should less than length of the array"); - array[_index] = array[array.length - 1]; - array.length = array.length - 1; - } - - //Deletes from mapping (bytes32 => bytes32[]) at index _index - function deleteArrayBytes32(bytes32 _key, uint256 _index) internal { - bytes32[] storage array = bytes32ArrayStorage[_key]; - require(_index < array.length, "Index should less than length of the array"); - array[_index] = array[array.length - 1]; - array.length = array.length - 1; - } - - //Deletes from mapping (bytes32 => uint[]) at index _index - function deleteArrayUint(bytes32 _key, uint256 _index) internal { - uint256[] storage array = uintArrayStorage[_key]; - require(_index < array.length, "Index should less than length of the array"); - array[_index] = array[array.length - 1]; - array.length = array.length - 1; - } - - //Deletes from mapping (bytes32 => string[]) at index _index - function deleteArrayString(bytes32 _key, uint256 _index) internal { - string[] storage array = stringArrayStorage[_key]; - require(_index < array.length, "Index should less than length of the array"); - array[_index] = array[array.length - 1]; - array.length = array.length - 1; - } - - //////////////////////////// - //// pushArray functions - /////////////////////////// - /// @notice Below are the helper functions to facilitate the storing the arrays of different data types. - /// Ex1- mapping(address => bytes32[]) tokensOwnedByTicker; - /// tokensOwnedByTicker[owner] = tokensOwnedByTicker[owner].push("xyz"); replace with - /// pushArray(keccak256(abi.encodePacked("tokensOwnedByTicker", owner), "xyz"); - - /// @notice use to store the values for the array - /// @param _key bytes32 type - /// @param _value [uint256, string, bytes32, address] any of the data type in array - function pushArray(bytes32 _key, address _value) internal { - addressArrayStorage[_key].push(_value); - } - - function pushArray(bytes32 _key, bytes32 _value) internal { - bytes32ArrayStorage[_key].push(_value); - } - - function pushArray(bytes32 _key, string _value) internal { - stringArrayStorage[_key].push(_value); - } - - function pushArray(bytes32 _key, uint256 _value) internal { - uintArrayStorage[_key].push(_value); - } - - ///////////////////////// - //// Set Array functions - //////////////////////// - /// @notice use to intialize the array - /// Ex1- mapping (address => address[]) public reputation; - /// reputation[0x1] = new address[](0); It can be replaced as - /// setArray(hash('reputation', 0x1), new address[](0)); - - function setArray(bytes32 _key, address[] _value) internal { - addressArrayStorage[_key] = _value; - } - - function setArray(bytes32 _key, uint256[] _value) internal { - uintArrayStorage[_key] = _value; - } - - function setArray(bytes32 _key, bytes32[] _value) internal { - bytes32ArrayStorage[_key] = _value; - } - - function setArray(bytes32 _key, string[] _value) internal { - stringArrayStorage[_key] = _value; - } - - ///////////////////////// - /// getArray functions - ///////////////////////// - /// @notice Get functions to get the array of the required data type - /// Ex1- mapping(address => bytes32[]) tokensOwnedByOwner; - /// getArrayBytes32(keccak256(abi.encodePacked("tokensOwnedByOwner", 0x1)); It return the bytes32 array - /// Ex2- uint256 _len = tokensOwnedByOwner[0x1].length; replace with - /// getArrayBytes32(keccak256(abi.encodePacked("tokensOwnedByOwner", 0x1)).length; - - function getArrayAddress(bytes32 _key) internal view returns(address[]) { - return addressArrayStorage[_key]; - } - - function getArrayBytes32(bytes32 _key) internal view returns(bytes32[]) { - return bytes32ArrayStorage[_key]; - } - - function getArrayString(bytes32 _key) internal view returns(string[]) { - return stringArrayStorage[_key]; - } - - function getArrayUint(bytes32 _key) internal view returns(uint[]) { - return uintArrayStorage[_key]; - } - - /////////////////////////////////// - /// setArrayIndexValue() functions - /////////////////////////////////// - /// @notice set the value of particular index of the address array - /// Ex1- mapping(bytes32 => address[]) moduleList; - /// general way is -- moduleList[moduleType][index] = temp; - /// It can be re-write as -- setArrayIndexValue(keccak256(abi.encodePacked('moduleList', moduleType)), index, temp); - - function setArrayIndexValue(bytes32 _key, uint256 _index, address _value) internal { - addressArrayStorage[_key][_index] = _value; - } - - function setArrayIndexValue(bytes32 _key, uint256 _index, uint256 _value) internal { - uintArrayStorage[_key][_index] = _value; - } - - function setArrayIndexValue(bytes32 _key, uint256 _index, bytes32 _value) internal { - bytes32ArrayStorage[_key][_index] = _value; - } - - function setArrayIndexValue(bytes32 _key, uint256 _index, string _value) internal { - stringArrayStorage[_key][_index] = _value; - } - - ///////////////////////////// - /// Public getters functions - ///////////////////////////// - - function getUintValues(bytes32 _variable) public view returns(uint256) { - return uintStorage[_variable]; - } - - function getBoolValues(bytes32 _variable) public view returns(bool) { - return boolStorage[_variable]; - } - - function getStringValues(bytes32 _variable) public view returns(string) { - return stringStorage[_variable]; - } - - function getAddressValues(bytes32 _variable) public view returns(address) { - return addressStorage[_variable]; - } - - function getBytes32Values(bytes32 _variable) public view returns(bytes32) { - return bytes32Storage[_variable]; - } - - function getBytesValues(bytes32 _variable) public view returns(bytes) { - return bytesStorage[_variable]; - } + mapping(bytes32 => uint256) internal uintStorage; + mapping(bytes32 => string) internal stringStorage; + mapping(bytes32 => address) internal addressStorage; + mapping(bytes32 => bytes) internal bytesStorage; + mapping(bytes32 => bool) internal boolStorage; + mapping(bytes32 => int256) internal intStorage; + mapping(bytes32 => bytes32) internal bytes32Storage; + + /// @notice Internal mappings use to store the array of different data types + mapping(bytes32 => bytes32[]) internal bytes32ArrayStorage; + mapping(bytes32 => uint256[]) internal uintArrayStorage; + mapping(bytes32 => address[]) internal addressArrayStorage; + mapping(bytes32 => string[]) internal stringArrayStorage; + + ////////////////// + //// set functions + ////////////////// + /// @notice Set the key values using the Overloaded `set` functions + /// Ex- string version = "0.0.1"; replace to + /// set(keccak256(abi.encodePacked("version"), "0.0.1"); + /// same for the other variables as well some more example listed below + /// ex1 - address securityTokenAddress = 0x123; replace to + /// set(keccak256(abi.encodePacked("securityTokenAddress"), 0x123); + /// ex2 - bytes32 tokenDetails = "I am ST20"; replace to + /// set(keccak256(abi.encodePacked("tokenDetails"), "I am ST20"); + /// ex3 - mapping(string => address) ownedToken; + /// set(keccak256(abi.encodePacked("ownedToken", "Chris")), 0x123); + /// ex4 - mapping(string => uint) tokenIndex; + /// tokenIndex["TOKEN"] = 1; replace to set(keccak256(abi.encodePacked("tokenIndex", "TOKEN"), 1); + /// ex5 - mapping(string => SymbolDetails) registeredSymbols; where SymbolDetails is the structure having different type of values as + /// {uint256 date, string name, address owner} etc. + /// registeredSymbols["TOKEN"].name = "MyFristToken"; replace to set(keccak256(abi.encodePacked("registeredSymbols_name", "TOKEN"), "MyFirstToken"); + /// More generalized- set(keccak256(abi.encodePacked("registeredSymbols_", "keyname"), "value"); + + function set(bytes32 _key, uint256 _value) internal { + uintStorage[_key] = _value; + } + + function set(bytes32 _key, address _value) internal { + addressStorage[_key] = _value; + } + + function set(bytes32 _key, bool _value) internal { + boolStorage[_key] = _value; + } + + function set(bytes32 _key, bytes32 _value) internal { + bytes32Storage[_key] = _value; + } + + function set(bytes32 _key, string _value) internal { + stringStorage[_key] = _value; + } + + //////////////////// + /// get functions + //////////////////// + /// @notice Get function use to get the value of the singleton state variables + /// Ex1- string public version = "0.0.1"; + /// string _version = getString(keccak256(abi.encodePacked("version")); + /// Ex2 - assert(temp1 == temp2); replace to + /// assert(getUint(keccak256(abi.encodePacked(temp1)) == getUint(keccak256(abi.encodePacked(temp2)); + /// Ex3 - mapping(string => SymbolDetails) registeredSymbols; where SymbolDetails is the structure having different type of values as + /// {uint256 date, string name, address owner} etc. + /// string _name = getString(keccak256(abi.encodePacked("registeredSymbols_name", "TOKEN")); + + function getBool(bytes32 _key) internal view returns (bool) { + return boolStorage[_key]; + } + + function getUint(bytes32 _key) internal view returns (uint256) { + return uintStorage[_key]; + } + + function getAddress(bytes32 _key) internal view returns (address) { + return addressStorage[_key]; + } + + function getString(bytes32 _key) internal view returns (string) { + return stringStorage[_key]; + } + + function getBytes32(bytes32 _key) internal view returns (bytes32) { + return bytes32Storage[_key]; + } + + + //////////////////////////// + // deleteArray functions + //////////////////////////// + /// @notice Function use to delete the array element. + /// Ex1- mapping(address => bytes32[]) tokensOwnedByOwner; + /// For deleting the item from array developers needs to create a funtion for that similarly + /// in this case we have the helper function deleteArrayBytes32() which will do it for us + /// deleteArrayBytes32(keccak256(abi.encodePacked("tokensOwnedByOwner", 0x1), 3); -- it will delete the index 3 + + + //Deletes from mapping (bytes32 => array[]) at index _index + function deleteArrayAddress(bytes32 _key, uint256 _index) internal { + address[] storage array = addressArrayStorage[_key]; + require(_index < array.length, "Index should less than length of the array"); + array[_index] = array[array.length - 1]; + array.length = array.length - 1; + } + + //Deletes from mapping (bytes32 => bytes32[]) at index _index + function deleteArrayBytes32(bytes32 _key, uint256 _index) internal { + bytes32[] storage array = bytes32ArrayStorage[_key]; + require(_index < array.length, "Index should less than length of the array"); + array[_index] = array[array.length - 1]; + array.length = array.length - 1; + } + + //Deletes from mapping (bytes32 => uint[]) at index _index + function deleteArrayUint(bytes32 _key, uint256 _index) internal { + uint256[] storage array = uintArrayStorage[_key]; + require(_index < array.length, "Index should less than length of the array"); + array[_index] = array[array.length - 1]; + array.length = array.length - 1; + } + + //Deletes from mapping (bytes32 => string[]) at index _index + function deleteArrayString(bytes32 _key, uint256 _index) internal { + string[] storage array = stringArrayStorage[_key]; + require(_index < array.length, "Index should less than length of the array"); + array[_index] = array[array.length - 1]; + array.length = array.length - 1; + } + + //////////////////////////// + //// pushArray functions + /////////////////////////// + /// @notice Below are the helper functions to facilitate the storing the arrays of different data types. + /// Ex1- mapping(address => bytes32[]) tokensOwnedByTicker; + /// tokensOwnedByTicker[owner] = tokensOwnedByTicker[owner].push("xyz"); replace with + /// pushArray(keccak256(abi.encodePacked("tokensOwnedByTicker", owner), "xyz"); + + /// @notice use to store the values for the array + /// @param _key bytes32 type + /// @param _value [uint256, string, bytes32, address] any of the data type in array + function pushArray(bytes32 _key, address _value) internal { + addressArrayStorage[_key].push(_value); + } + + function pushArray(bytes32 _key, bytes32 _value) internal { + bytes32ArrayStorage[_key].push(_value); + } + + function pushArray(bytes32 _key, string _value) internal { + stringArrayStorage[_key].push(_value); + } + + function pushArray(bytes32 _key, uint256 _value) internal { + uintArrayStorage[_key].push(_value); + } + + ///////////////////////// + //// Set Array functions + //////////////////////// + /// @notice use to intialize the array + /// Ex1- mapping (address => address[]) public reputation; + /// reputation[0x1] = new address[](0); It can be replaced as + /// setArray(hash('reputation', 0x1), new address[](0)); + + function setArray(bytes32 _key, address[] _value) internal { + addressArrayStorage[_key] = _value; + } + + function setArray(bytes32 _key, uint256[] _value) internal { + uintArrayStorage[_key] = _value; + } + + function setArray(bytes32 _key, bytes32[] _value) internal { + bytes32ArrayStorage[_key] = _value; + } + + function setArray(bytes32 _key, string[] _value) internal { + stringArrayStorage[_key] = _value; + } + + ///////////////////////// + /// getArray functions + ///////////////////////// + /// @notice Get functions to get the array of the required data type + /// Ex1- mapping(address => bytes32[]) tokensOwnedByOwner; + /// getArrayBytes32(keccak256(abi.encodePacked("tokensOwnedByOwner", 0x1)); It return the bytes32 array + /// Ex2- uint256 _len = tokensOwnedByOwner[0x1].length; replace with + /// getArrayBytes32(keccak256(abi.encodePacked("tokensOwnedByOwner", 0x1)).length; + + function getArrayAddress(bytes32 _key) internal view returns(address[]) { + return addressArrayStorage[_key]; + } + + function getArrayBytes32(bytes32 _key) internal view returns(bytes32[]) { + return bytes32ArrayStorage[_key]; + } + + function getArrayString(bytes32 _key) internal view returns(string[]) { + return stringArrayStorage[_key]; + } + + function getArrayUint(bytes32 _key) internal view returns(uint[]) { + return uintArrayStorage[_key]; + } + + /////////////////////////////////// + /// setArrayIndexValue() functions + /////////////////////////////////// + /// @notice set the value of particular index of the address array + /// Ex1- mapping(bytes32 => address[]) moduleList; + /// general way is -- moduleList[moduleType][index] = temp; + /// It can be re-write as -- setArrayIndexValue(keccak256(abi.encodePacked('moduleList', moduleType)), index, temp); + + function setArrayIndexValue(bytes32 _key, uint256 _index, address _value) internal { + addressArrayStorage[_key][_index] = _value; + } + + function setArrayIndexValue(bytes32 _key, uint256 _index, uint256 _value) internal { + uintArrayStorage[_key][_index] = _value; + } + + function setArrayIndexValue(bytes32 _key, uint256 _index, bytes32 _value) internal { + bytes32ArrayStorage[_key][_index] = _value; + } + + function setArrayIndexValue(bytes32 _key, uint256 _index, string _value) internal { + stringArrayStorage[_key][_index] = _value; + } + + ///////////////////////////// + /// Public getters functions + ///////////////////////////// + + function getUintValues(bytes32 _variable) public view returns(uint256) { + return uintStorage[_variable]; + } + + function getBoolValues(bytes32 _variable) public view returns(bool) { + return boolStorage[_variable]; + } + + function getStringValues(bytes32 _variable) public view returns(string) { + return stringStorage[_variable]; + } + + function getAddressValues(bytes32 _variable) public view returns(address) { + return addressStorage[_variable]; + } + + function getBytes32Values(bytes32 _variable) public view returns(bytes32) { + return bytes32Storage[_variable]; + } + + function getBytesValues(bytes32 _variable) public view returns(bytes) { + return bytesStorage[_variable]; + } } From 1aaef5058a6a3c721c9799e6a516591c5ab97fde Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 5 Oct 2018 14:57:00 -0300 Subject: [PATCH 093/142] fixed linter errors in helpers, proxy, storage contracts --- contracts/helpers/PolyToken.sol | 306 +++++++++--------- contracts/libraries/KindMath.sol | 76 ++--- contracts/libraries/TokenLib.sol | 2 +- contracts/libraries/VersionUtils.sol | 24 +- contracts/mocks/MockOracle.sol | 2 +- contracts/mocks/MockPolyOracle.sol | 2 +- contracts/mocks/PolyTokenFaucet.sol | 50 +-- contracts/oracles/MakerDAOOracle.sol | 4 +- contracts/oracles/PolyOracle.sol | 2 +- contracts/proxy/ModuleRegistryProxy.sol | 4 +- contracts/proxy/OwnedUpgradeabilityProxy.sol | 212 ++++++------ contracts/proxy/Proxy.sol | 80 ++--- .../proxy/SecurityTokenRegistryProxy.sol | 4 +- contracts/proxy/UpgradeabilityProxy.sol | 50 +-- contracts/storage/EternalStorage.sol | 10 +- 15 files changed, 414 insertions(+), 414 deletions(-) diff --git a/contracts/helpers/PolyToken.sol b/contracts/helpers/PolyToken.sol index 0c1c79eac..aea5f200d 100644 --- a/contracts/helpers/PolyToken.sol +++ b/contracts/helpers/PolyToken.sol @@ -30,32 +30,32 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * @dev Math operations with safety checks that throw on error */ library SafeMath { - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - if (a == 0) { - return 0; + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + uint256 c = a * b; + assert(c / a == b); + return c; + } + + function div(uint256 a, uint256 b) internal pure returns (uint256) { + // assert(b > 0); // Solidity automatically throws when dividing by 0 + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + return c; + } + + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + assert(b <= a); + return a - b; + } + + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + assert(c >= a); + return c; } - uint256 c = a * b; - assert(c / a == b); - return c; - } - - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return c; - } - - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - assert(b <= a); - return a - b; - } - - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - assert(c >= a); - return c; - } } /** @@ -65,134 +65,134 @@ library SafeMath { * @dev https://github.com/ethereum/EIPs/issues/20 */ contract PolyToken is IERC20 { - using SafeMath for uint256; - - // Poly Token parameters - string public name = 'Polymath'; - string public symbol = 'POLY'; - uint8 public constant decimals = 18; - uint256 public constant decimalFactor = 10 ** uint256(decimals); - uint256 public constant totalSupply = 1000000000 * decimalFactor; - mapping (address => uint256) balances; - mapping (address => mapping (address => uint256)) internal allowed; - - event Transfer(address indexed from, address indexed to, uint256 value); - event Approval(address indexed owner, address indexed spender, uint256 value); - - /** - * @dev Constructor for Poly creation - * @dev Assigns the totalSupply to the PolyDistribution contract - */ - constructor (address _polyDistributionContractAddress) public { - require(_polyDistributionContractAddress != address(0)); - balances[_polyDistributionContractAddress] = totalSupply; - emit Transfer(address(0), _polyDistributionContractAddress, totalSupply); - } - - /** - * @dev Gets the balance of the specified address. - * @param _owner The address to query the the balance of. - * @return An uint256 representing the amount owned by the passed address. - */ - function balanceOf(address _owner) public view returns (uint256 balance) { - return balances[_owner]; - } - - /** - * @dev Function to check the amount of tokens that an owner allowed to a spender. - * @param _owner address The address which owns the funds. - * @param _spender address The address which will spend the funds. - * @return A uint256 specifying the amount of tokens still available for the spender. - */ - function allowance(address _owner, address _spender) public view returns (uint256) { - return allowed[_owner][_spender]; - } - - /** - * @dev transfer token for a specified address - * @param _to The address to transfer to. - * @param _value The amount to be transferred. - */ - function transfer(address _to, uint256 _value) public returns (bool) { - require(_to != address(0)); - require(_value <= balances[msg.sender]); - - // SafeMath.sub will throw if there is not enough balance. - balances[msg.sender] = balances[msg.sender].sub(_value); - balances[_to] = balances[_to].add(_value); - emit Transfer(msg.sender, _to, _value); - return true; - } - - /** - * @dev Transfer tokens from one address to another - * @param _from address The address which you want to send tokens from - * @param _to address The address which you want to transfer to - * @param _value uint256 the amount of tokens to be transferred - */ - function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { - require(_to != address(0)); - require(_value <= balances[_from]); - require(_value <= allowed[_from][msg.sender]); - - balances[_from] = balances[_from].sub(_value); - balances[_to] = balances[_to].add(_value); - allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); - emit Transfer(_from, _to, _value); - return true; - } - - /** - * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. - * - * Beware that changing an allowance with this method brings the risk that someone may use both the old - * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this - * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: - * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * @param _spender The address which will spend the funds. - * @param _value The amount of tokens to be spent. - */ - function approve(address _spender, uint256 _value) public returns (bool) { - allowed[msg.sender][_spender] = _value; - emit Approval(msg.sender, _spender, _value); - return true; - } - - /** - * @dev Increase the amount of tokens that an owner allowed to a spender. - * - * approve should be called when allowed[_spender] == 0. To increment - * allowed value is better to use this function to avoid 2 calls (and wait until - * the first transaction is mined) - * From MonolithDAO Token.sol - * @param _spender The address which will spend the funds. - * @param _addedValue The amount of tokens to increase the allowance by. - */ - function increaseApproval(address _spender, uint _addedValue) public returns (bool) { - allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue); - emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); - return true; - } - - /** - * @dev Decrease the amount of tokens that an owner allowed to a spender. - * - * approve should be called when allowed[_spender] == 0. To decrement - * allowed value is better to use this function to avoid 2 calls (and wait until - * the first transaction is mined) - * From MonolithDAO Token.sol - * @param _spender The address which will spend the funds. - * @param _subtractedValue The amount of tokens to decrease the allowance by. - */ - function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) { - uint oldValue = allowed[msg.sender][_spender]; - if (_subtractedValue > oldValue) { - allowed[msg.sender][_spender] = 0; - } else { - allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); + using SafeMath for uint256; + + // Poly Token parameters + string public name = "Polymath"; + string public symbol = "POLY"; + uint8 public constant decimals = 18; + uint256 public constant decimalFactor = 10 ** uint256(decimals); + uint256 public constant totalSupply = 1000000000 * decimalFactor; + mapping (address => uint256) balances; + mapping (address => mapping (address => uint256)) internal allowed; + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + + /** + * @dev Constructor for Poly creation + * @dev Assigns the totalSupply to the PolyDistribution contract + */ + constructor (address _polyDistributionContractAddress) public { + require(_polyDistributionContractAddress != address(0)); + balances[_polyDistributionContractAddress] = totalSupply; + emit Transfer(address(0), _polyDistributionContractAddress, totalSupply); + } + + /** + * @dev Gets the balance of the specified address. + * @param _owner The address to query the the balance of. + * @return An uint256 representing the amount owned by the passed address. + */ + function balanceOf(address _owner) public view returns (uint256 balance) { + return balances[_owner]; + } + + /** + * @dev Function to check the amount of tokens that an owner allowed to a spender. + * @param _owner address The address which owns the funds. + * @param _spender address The address which will spend the funds. + * @return A uint256 specifying the amount of tokens still available for the spender. + */ + function allowance(address _owner, address _spender) public view returns (uint256) { + return allowed[_owner][_spender]; + } + + /** + * @dev transfer token for a specified address + * @param _to The address to transfer to. + * @param _value The amount to be transferred. + */ + function transfer(address _to, uint256 _value) public returns (bool) { + require(_to != address(0)); + require(_value <= balances[msg.sender]); + + // SafeMath.sub will throw if there is not enough balance. + balances[msg.sender] = balances[msg.sender].sub(_value); + balances[_to] = balances[_to].add(_value); + emit Transfer(msg.sender, _to, _value); + return true; + } + + /** + * @dev Transfer tokens from one address to another + * @param _from address The address which you want to send tokens from + * @param _to address The address which you want to transfer to + * @param _value uint256 the amount of tokens to be transferred + */ + function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { + require(_to != address(0)); + require(_value <= balances[_from]); + require(_value <= allowed[_from][msg.sender]); + + balances[_from] = balances[_from].sub(_value); + balances[_to] = balances[_to].add(_value); + allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); + emit Transfer(_from, _to, _value); + return true; + } + + /** + * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. + * + * Beware that changing an allowance with this method brings the risk that someone may use both the old + * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this + * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * @param _spender The address which will spend the funds. + * @param _value The amount of tokens to be spent. + */ + function approve(address _spender, uint256 _value) public returns (bool) { + allowed[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + return true; + } + + /** + * @dev Increase the amount of tokens that an owner allowed to a spender. + * + * approve should be called when allowed[_spender] == 0. To increment + * allowed value is better to use this function to avoid 2 calls (and wait until + * the first transaction is mined) + * From MonolithDAO Token.sol + * @param _spender The address which will spend the funds. + * @param _addedValue The amount of tokens to increase the allowance by. + */ + function increaseApproval(address _spender, uint _addedValue) public returns (bool) { + allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue); + emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); + return true; + } + + /** + * @dev Decrease the amount of tokens that an owner allowed to a spender. + * + * approve should be called when allowed[_spender] == 0. To decrement + * allowed value is better to use this function to avoid 2 calls (and wait until + * the first transaction is mined) + * From MonolithDAO Token.sol + * @param _spender The address which will spend the funds. + * @param _subtractedValue The amount of tokens to decrease the allowance by. + */ + function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) { + uint oldValue = allowed[msg.sender][_spender]; + if (_subtractedValue > oldValue) { + allowed[msg.sender][_spender] = 0; + } else { + allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); + } + emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); + return true; } - emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); - return true; - } } diff --git a/contracts/libraries/KindMath.sol b/contracts/libraries/KindMath.sol index a9cce4546..850926088 100644 --- a/contracts/libraries/KindMath.sol +++ b/contracts/libraries/KindMath.sol @@ -8,46 +8,46 @@ pragma solidity ^0.4.24; */ library KindMath { - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // Gas optimization: this is cheaper than requireing 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 - if (a == 0) { - return 0; - } + /** + * @dev Multiplies two numbers, throws on overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { + // Gas optimization: this is cheaper than requireing 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 + if (a == 0) { + return 0; + } - c = a * b; - require(c / a == b, "mul overflow"); - return c; - } + c = a * b; + require(c / a == b, "mul overflow"); + return c; + } - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // require(b > 0); // Solidity automatically throws when dividing by 0 - // uint256 c = a / b; - // require(a == b * c + a % b); // There is no case in which this doesn't hold - return a / b; - } + /** + * @dev Integer division of two numbers, truncating the quotient. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + // require(b > 0); // Solidity automatically throws when dividing by 0 + // uint256 c = a / b; + // require(a == b * c + a % b); // There is no case in which this doesn't hold + return a / b; + } - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - require(b <= a, "sub overflow"); - return a - b; - } + /** + * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + require(b <= a, "sub overflow"); + return a - b; + } - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256 c) { - c = a + b; - require(c >= a, "add overflow"); - return c; - } + /** + * @dev Adds two numbers, throws on overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256 c) { + c = a + b; + require(c >= a, "add overflow"); + return c; + } } diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index e8c76a4ce..af4b98fa6 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -95,7 +95,7 @@ library TokenLib { function getValueAt(Checkpoint[] storage _checkpoints, uint256 _checkpointId, uint256 _currentValue) public view returns(uint256) { //Checkpoint id 0 is when the token is first created - everyone has a zero balance if (_checkpointId == 0) { - return 0; + return 0; } if (_checkpoints.length == 0) { return _currentValue; diff --git a/contracts/libraries/VersionUtils.sol b/contracts/libraries/VersionUtils.sol index 41689713d..2650913ce 100644 --- a/contracts/libraries/VersionUtils.sol +++ b/contracts/libraries/VersionUtils.sol @@ -61,12 +61,12 @@ library VersionUtils { if (counter != _version1.length) { counter = 0; for (uint8 i = 0; i < _version1.length; i++) { - if (_version2[i] > _version1[i]) - return true; - else if (_version2[i] < _version1[i]) - return false; - else - counter++; + if (_version2[i] > _version1[i]) + return true; + else if (_version2[i] < _version1[i]) + return false; + else + counter++; } if (counter == _version1.length - 1) return true; @@ -92,12 +92,12 @@ library VersionUtils { if (counter != _version1.length) { counter = 0; for (uint8 i = 0; i < _version1.length; i++) { - if (_version1[i] > _version2[i]) - return true; - else if (_version1[i] < _version2[i]) - return false; - else - counter++; + if (_version1[i] > _version2[i]) + return true; + else if (_version1[i] < _version2[i]) + return false; + else + counter++; } if (counter == _version1.length - 1) return true; diff --git a/contracts/mocks/MockOracle.sol b/contracts/mocks/MockOracle.sol index 06ebbcc88..d7cf14a2a 100644 --- a/contracts/mocks/MockOracle.sol +++ b/contracts/mocks/MockOracle.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.24; -import '../interfaces/IOracle.sol'; +import "../interfaces/IOracle.sol"; contract MockOracle is IOracle { diff --git a/contracts/mocks/MockPolyOracle.sol b/contracts/mocks/MockPolyOracle.sol index bde3625e2..681bb2681 100644 --- a/contracts/mocks/MockPolyOracle.sol +++ b/contracts/mocks/MockPolyOracle.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.24; -import '../oracles/PolyOracle.sol'; +import "../oracles/PolyOracle.sol"; contract MockPolyOracle is PolyOracle { diff --git a/contracts/mocks/PolyTokenFaucet.sol b/contracts/mocks/PolyTokenFaucet.sol index 73580b9f9..aa106bf0e 100644 --- a/contracts/mocks/PolyTokenFaucet.sol +++ b/contracts/mocks/PolyTokenFaucet.sol @@ -117,31 +117,31 @@ contract PolyTokenFaucet { return true; } - /** - * @dev Decrease the amount of tokens that an owner allowed to a spender. - * - * approve should be called when allowed[_spender] == 0. To decrement - * allowed value is better to use this function to avoid 2 calls (and wait until - * the first transaction is mined) - * From MonolithDAO Token.sol - * @param _spender The address which will spend the funds. - * @param _subtractedValue The amount of tokens to decrease the allowance by. - */ - function decreaseApproval( - address _spender, - uint _subtractedValue - ) - public - returns (bool) - { - uint oldValue = allowed[msg.sender][_spender]; - if (_subtractedValue > oldValue) { - allowed[msg.sender][_spender] = 0; - } else { - allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); + /** + * @dev Decrease the amount of tokens that an owner allowed to a spender. + * + * approve should be called when allowed[_spender] == 0. To decrement + * allowed value is better to use this function to avoid 2 calls (and wait until + * the first transaction is mined) + * From MonolithDAO Token.sol + * @param _spender The address which will spend the funds. + * @param _subtractedValue The amount of tokens to decrease the allowance by. + */ + function decreaseApproval( + address _spender, + uint _subtractedValue + ) + public + returns (bool) + { + uint oldValue = allowed[msg.sender][_spender]; + if (_subtractedValue > oldValue) { + allowed[msg.sender][_spender] = 0; + } else { + allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); + } + emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); + return true; } - emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); - return true; - } } diff --git a/contracts/oracles/MakerDAOOracle.sol b/contracts/oracles/MakerDAOOracle.sol index 63d8b73cb..5ed3d02c7 100644 --- a/contracts/oracles/MakerDAOOracle.sol +++ b/contracts/oracles/MakerDAOOracle.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.24; -import '../interfaces/IOracle.sol'; -import '../external/IMedianizer.sol'; +import "../interfaces/IOracle.sol"; +import "../external/IMedianizer.sol"; import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; contract MakerDAOOracle is IOracle, Ownable { diff --git a/contracts/oracles/PolyOracle.sol b/contracts/oracles/PolyOracle.sol index 005d1677b..2bcf2b8d1 100644 --- a/contracts/oracles/PolyOracle.sol +++ b/contracts/oracles/PolyOracle.sol @@ -3,7 +3,7 @@ pragma solidity ^0.4.24; import "../external/oraclizeAPI.sol"; import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; -import '../interfaces/IOracle.sol'; +import "../interfaces/IOracle.sol"; contract PolyOracle is usingOraclize, IOracle, Ownable { using SafeMath for uint256; diff --git a/contracts/proxy/ModuleRegistryProxy.sol b/contracts/proxy/ModuleRegistryProxy.sol index 1c4fc945e..ae77cd6b2 100644 --- a/contracts/proxy/ModuleRegistryProxy.sol +++ b/contracts/proxy/ModuleRegistryProxy.sol @@ -6,8 +6,8 @@ import "./OwnedUpgradeabilityProxy.sol"; /** * @title ModuleRegistryProxy - * @dev This proxy holds the storage of the token contract and delegates every call to the current implementation set. - * Besides, it allows to upgrade the token's behaviour towards further implementations, and provides basic + * @dev This proxy holds the storage of the ModuleRegistry contract and delegates every call to the current implementation set. + * Besides, it allows upgrading the contract's behaviour towards further implementations, and provides basic * authorization control functionalities */ contract ModuleRegistryProxy is EternalStorage, OwnedUpgradeabilityProxy { diff --git a/contracts/proxy/OwnedUpgradeabilityProxy.sol b/contracts/proxy/OwnedUpgradeabilityProxy.sol index 8e4eb6553..e1890a243 100644 --- a/contracts/proxy/OwnedUpgradeabilityProxy.sol +++ b/contracts/proxy/OwnedUpgradeabilityProxy.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.18; -import './UpgradeabilityProxy.sol'; +import "./UpgradeabilityProxy.sol"; /** * @title OwnedUpgradeabilityProxy @@ -8,111 +8,111 @@ import './UpgradeabilityProxy.sol'; */ contract OwnedUpgradeabilityProxy is UpgradeabilityProxy { - // Owner of the contract - address private __upgradeabilityOwner; - - /** - * @dev Event to show ownership has been transferred - * @param _previousOwner representing the address of the previous owner - * @param _newOwner representing the address of the new owner - */ - event ProxyOwnershipTransferred(address _previousOwner, address _newOwner); - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier ifOwner() { - if (msg.sender == _upgradeabilityOwner()) { - _; - } else { - _fallback(); + // Owner of the contract + address private __upgradeabilityOwner; + + /** + * @dev Event to show ownership has been transferred + * @param _previousOwner representing the address of the previous owner + * @param _newOwner representing the address of the new owner + */ + event ProxyOwnershipTransferred(address _previousOwner, address _newOwner); + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier ifOwner() { + if (msg.sender == _upgradeabilityOwner()) { + _; + } else { + _fallback(); + } + } + + /** + * @dev the constructor sets the original owner of the contract to the sender account. + */ + constructor() public { + _setUpgradeabilityOwner(msg.sender); + } + + /** + * @dev Tells the address of the owner + * @return the address of the owner + */ + function _upgradeabilityOwner() internal view returns (address) { + return __upgradeabilityOwner; + } + + /** + * @dev Sets the address of the owner + */ + function _setUpgradeabilityOwner(address _newUpgradeabilityOwner) internal { + require(_newUpgradeabilityOwner != address(0), "Address should not be 0x"); + __upgradeabilityOwner = _newUpgradeabilityOwner; + } + + /** + * @notice Internal function to provide the address of the implementation contract + */ + function _implementation() internal view returns (address) { + return __implementation; + } + + /** + * @dev Tells the address of the proxy owner + * @return the address of the proxy owner + */ + function proxyOwner() external ifOwner returns (address) { + return _upgradeabilityOwner(); + } + + /** + * @dev Tells the version name of the current implementation + * @return string representing the name of the current version + */ + function version() external ifOwner returns (string) { + return __version; + } + + /** + * @dev Tells the address of the current implementation + * @return address of the current implementation + */ + function implementation() external ifOwner returns (address) { + _implementation(); + } + + /** + * @dev Allows the current owner to transfer control of the contract to a newOwner. + * @param _newOwner The address to transfer ownership to. + */ + function transferProxyOwnership(address _newOwner) external ifOwner { + require(_newOwner != address(0), "Address should not be 0x"); + emit ProxyOwnershipTransferred(_upgradeabilityOwner(), _newOwner); + _setUpgradeabilityOwner(_newOwner); + } + + /** + * @dev Allows the upgradeability owner to upgrade the current version of the proxy. + * @param _newVersion representing the version name of the new implementation to be set. + * @param _newImplementation representing the address of the new implementation to be set. + */ + function upgradeTo(string _newVersion, address _newImplementation) external ifOwner { + _upgradeTo(_newVersion, _newImplementation); + } + + /** + * @dev Allows the upgradeability owner to upgrade the current version of the proxy and call the new implementation + * to initialize whatever is needed through a low level call. + * @param _newVersion representing the version name of the new implementation to be set. + * @param _newImplementation representing the address of the new implementation to be set. + * @param _data represents the msg.data to bet sent in the low level call. This parameter may include the function + * signature of the implementation to be called with the needed payload + */ + function upgradeToAndCall(string _newVersion, address _newImplementation, bytes _data) payable external ifOwner { + _upgradeTo(_newVersion, _newImplementation); + require(address(this).call.value(msg.value)(_data), "Fail in executing the function of implementation contract"); } - } - - /** - * @dev the constructor sets the original owner of the contract to the sender account. - */ - constructor() public { - _setUpgradeabilityOwner(msg.sender); - } - - /** - * @dev Tells the address of the owner - * @return the address of the owner - */ - function _upgradeabilityOwner() internal view returns (address) { - return __upgradeabilityOwner; - } - - /** - * @dev Sets the address of the owner - */ - function _setUpgradeabilityOwner(address _newUpgradeabilityOwner) internal { - require(_newUpgradeabilityOwner != address(0), "Address should not be 0x"); - __upgradeabilityOwner = _newUpgradeabilityOwner; - } - - /** - * @notice Internal function to provide the address of the implementation contract - */ - function _implementation() internal view returns (address) { - return __implementation; - } - - /** - * @dev Tells the address of the proxy owner - * @return the address of the proxy owner - */ - function proxyOwner() external ifOwner returns (address) { - return _upgradeabilityOwner(); - } - - /** - * @dev Tells the version name of the current implementation - * @return string representing the name of the current version - */ - function version() external ifOwner returns (string) { - return __version; - } - - /** - * @dev Tells the address of the current implementation - * @return address of the current implementation - */ - function implementation() external ifOwner returns (address) { - _implementation(); - } - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param _newOwner The address to transfer ownership to. - */ - function transferProxyOwnership(address _newOwner) external ifOwner { - require(_newOwner != address(0), "Address should not be 0x"); - emit ProxyOwnershipTransferred(_upgradeabilityOwner(), _newOwner); - _setUpgradeabilityOwner(_newOwner); - } - - /** - * @dev Allows the upgradeability owner to upgrade the current version of the proxy. - * @param _newVersion representing the version name of the new implementation to be set. - * @param _newImplementation representing the address of the new implementation to be set. - */ - function upgradeTo(string _newVersion, address _newImplementation) external ifOwner { - _upgradeTo(_newVersion, _newImplementation); - } - - /** - * @dev Allows the upgradeability owner to upgrade the current version of the proxy and call the new implementation - * to initialize whatever is needed through a low level call. - * @param _newVersion representing the version name of the new implementation to be set. - * @param _newImplementation representing the address of the new implementation to be set. - * @param _data represents the msg.data to bet sent in the low level call. This parameter may include the function - * signature of the implementation to be called with the needed payload - */ - function upgradeToAndCall(string _newVersion, address _newImplementation, bytes _data) payable external ifOwner { - _upgradeTo(_newVersion, _newImplementation); - require(address(this).call.value(msg.value)(_data), "Fail in executing the function of implementation contract"); - } } diff --git a/contracts/proxy/Proxy.sol b/contracts/proxy/Proxy.sol index 16fc32725..adcfc8f46 100644 --- a/contracts/proxy/Proxy.sol +++ b/contracts/proxy/Proxy.sol @@ -6,46 +6,46 @@ pragma solidity ^0.4.24; */ contract Proxy { - /** - * @dev Tells the address of the implementation where every call will be delegated. - * @return address of the implementation to which it will be delegated - */ - function _implementation() internal view returns (address); - - /** - * @dev Fallback function. - * Implemented entirely in `_fallback`. - */ - function _fallback() internal { - _delegate(_implementation()); - } - - /** - * @dev Fallback function allowing to perform a delegatecall to the given implementation. - * This function will return whatever the implementation call returns - */ - function _delegate(address implementation) internal { - assembly { - // Copy msg.data. We take full control of memory in this inline assembly - // block because it will not return to Solidity code. We overwrite the - // Solidity scratch pad at memory position 0. - calldatacopy(0, 0, calldatasize) - - // Call the implementation. - // out and outsize are 0 because we don't know the size yet. - let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) - - // Copy the returned data. - returndatacopy(0, 0, returndatasize) - - switch result - // delegatecall returns 0 on error. - case 0 { revert(0, returndatasize) } - default { return(0, returndatasize) } + /** + * @dev Tells the address of the implementation where every call will be delegated. + * @return address of the implementation to which it will be delegated + */ + function _implementation() internal view returns (address); + + /** + * @dev Fallback function. + * Implemented entirely in `_fallback`. + */ + function _fallback() internal { + _delegate(_implementation()); } - } - function () payable public { - _fallback(); - } + /** + * @dev Fallback function allowing to perform a delegatecall to the given implementation. + * This function will return whatever the implementation call returns + */ + function _delegate(address implementation) internal { + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize) + + // Call the implementation. + // out and outsize are 0 because we don't know the size yet. + let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) + + // Copy the returned data. + returndatacopy(0, 0, returndatasize) + + switch result + // delegatecall returns 0 on error. + case 0 { revert(0, returndatasize) } + default { return(0, returndatasize) } + } + } + + function () public payable { + _fallback(); + } } \ No newline at end of file diff --git a/contracts/proxy/SecurityTokenRegistryProxy.sol b/contracts/proxy/SecurityTokenRegistryProxy.sol index 07a41d540..3ffb3c32e 100644 --- a/contracts/proxy/SecurityTokenRegistryProxy.sol +++ b/contracts/proxy/SecurityTokenRegistryProxy.sol @@ -6,8 +6,8 @@ import "./OwnedUpgradeabilityProxy.sol"; /** * @title SecurityTokenRegistryProxy - * @dev This proxy holds the storage of the token contract and delegates every call to the current implementation set. - * Besides, it allows to upgrade the token's behaviour towards further implementations, and provides basic + * @dev This proxy holds the storage of the SecurityTokenRegistry contract and delegates every call to the current implementation set. + * Besides, it allows to upgrade the SecurityTokenRegistry's behaviour towards further implementations, and provides basic * authorization control functionalities */ contract SecurityTokenRegistryProxy is EternalStorage, OwnedUpgradeabilityProxy { diff --git a/contracts/proxy/UpgradeabilityProxy.sol b/contracts/proxy/UpgradeabilityProxy.sol index 7bd11f61c..52bc121a9 100644 --- a/contracts/proxy/UpgradeabilityProxy.sol +++ b/contracts/proxy/UpgradeabilityProxy.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.24; import "./Proxy.sol"; -import 'openzeppelin-solidity/contracts/AddressUtils.sol'; +import "openzeppelin-solidity/contracts/AddressUtils.sol"; /** * @title UpgradeabilityProxy @@ -9,32 +9,32 @@ import 'openzeppelin-solidity/contracts/AddressUtils.sol'; */ contract UpgradeabilityProxy is Proxy { - // Version name of the current implementation - string internal __version; + // Version name of the current implementation + string internal __version; - // Address of the current implementation - address internal __implementation; + // Address of the current implementation + address internal __implementation; - /** - * @dev This event will be emitted every time the implementation gets upgraded - * @param _newVersion representing the version name of the upgraded implementation - * @param _newImplementation representing the address of the upgraded implementation - */ - event Upgraded(string _newVersion, address indexed _newImplementation); + /** + * @dev This event will be emitted every time the implementation gets upgraded + * @param _newVersion representing the version name of the upgraded implementation + * @param _newImplementation representing the address of the upgraded implementation + */ + event Upgraded(string _newVersion, address indexed _newImplementation); - /** - * @dev Upgrades the implementation address - * @param _newVersion representing the version name of the new implementation to be set - * @param _newImplementation representing the address of the new implementation to be set - */ - function _upgradeTo(string _newVersion, address _newImplementation) internal { - require(__implementation != _newImplementation && _newImplementation != address(0), "Old address is not allowed and implementation address should not be 0x"); - require(AddressUtils.isContract(_newImplementation), "Cannot set a proxy implementation to a non-contract address"); - require(bytes(_newVersion).length > 0, "Version should not be empty string"); - require(keccak256(abi.encodePacked(__version)) != keccak256(abi.encodePacked(_newVersion))); - __version = _newVersion; - __implementation = _newImplementation; - emit Upgraded(_newVersion, _newImplementation); - } + /** + * @dev Upgrades the implementation address + * @param _newVersion representing the version name of the new implementation to be set + * @param _newImplementation representing the address of the new implementation to be set + */ + function _upgradeTo(string _newVersion, address _newImplementation) internal { + require(__implementation != _newImplementation && _newImplementation != address(0), "Old address is not allowed and implementation address should not be 0x"); + require(AddressUtils.isContract(_newImplementation), "Cannot set a proxy implementation to a non-contract address"); + require(bytes(_newVersion).length > 0, "Version should not be empty string"); + require(keccak256(abi.encodePacked(__version)) != keccak256(abi.encodePacked(_newVersion))); + __version = _newVersion; + __implementation = _newImplementation; + emit Upgraded(_newVersion, _newImplementation); + } } \ No newline at end of file diff --git a/contracts/storage/EternalStorage.sol b/contracts/storage/EternalStorage.sol index f75782dd3..637b5f2f3 100644 --- a/contracts/storage/EternalStorage.sol +++ b/contracts/storage/EternalStorage.sol @@ -2,7 +2,7 @@ pragma solidity ^0.4.24; contract EternalStorage { - /// @notice Internal mappings use to store all kind on data into the contract + /// @notice Internal mappings used to store all kinds on data into the contract mapping(bytes32 => uint256) internal uintStorage; mapping(bytes32 => string) internal stringStorage; mapping(bytes32 => address) internal addressStorage; @@ -11,7 +11,7 @@ contract EternalStorage { mapping(bytes32 => int256) internal intStorage; mapping(bytes32 => bytes32) internal bytes32Storage; - /// @notice Internal mappings use to store the array of different data types + /// @notice Internal mappings used to store arrays of different data types mapping(bytes32 => bytes32[]) internal bytes32ArrayStorage; mapping(bytes32 => uint256[]) internal uintArrayStorage; mapping(bytes32 => address[]) internal addressArrayStorage; @@ -93,7 +93,7 @@ contract EternalStorage { //////////////////////////// // deleteArray functions //////////////////////////// - /// @notice Function use to delete the array element. + /// @notice Function used to delete the array element. /// Ex1- mapping(address => bytes32[]) tokensOwnedByOwner; /// For deleting the item from array developers needs to create a funtion for that similarly /// in this case we have the helper function deleteArrayBytes32() which will do it for us @@ -135,7 +135,7 @@ contract EternalStorage { //////////////////////////// //// pushArray functions /////////////////////////// - /// @notice Below are the helper functions to facilitate the storing the arrays of different data types. + /// @notice Below are the helper functions to facilitate storing arrays of different data types. /// Ex1- mapping(address => bytes32[]) tokensOwnedByTicker; /// tokensOwnedByTicker[owner] = tokensOwnedByTicker[owner].push("xyz"); replace with /// pushArray(keccak256(abi.encodePacked("tokensOwnedByTicker", owner), "xyz"); @@ -162,7 +162,7 @@ contract EternalStorage { ///////////////////////// //// Set Array functions //////////////////////// - /// @notice use to intialize the array + /// @notice used to intialize the array /// Ex1- mapping (address => address[]) public reputation; /// reputation[0x1] = new address[](0); It can be replaced as /// setArray(hash('reputation', 0x1), new address[](0)); From e4a6eee922a604a63eaa1f820e26a2c8ef786434 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 5 Oct 2018 15:14:10 -0300 Subject: [PATCH 094/142] fixed linter errors in MR and STR --- contracts/ModuleRegistry.sol | 93 ++++++++++++++--------------- contracts/SecurityTokenRegistry.sol | 78 ++++++++++++++++-------- 2 files changed, 99 insertions(+), 72 deletions(-) diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index c1269c331..b7b85c2b5 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -60,7 +60,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { - require(msg.sender == owner()); + require(msg.sender == owner(),"sender must be owner"); _; } @@ -103,7 +103,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } function initialize(address _polymathRegistry, address _owner) external payable { - require(!getBool(Encoder.getKey("initialised"))); + require(!getBool(Encoder.getKey("initialised")),"already initialized"); require(_owner != address(0) && _polymathRegistry != address(0), "0x address is invalid"); set(Encoder.getKey("polymathRegistry"), _polymathRegistry); set(Encoder.getKey("owner"), _owner); @@ -119,16 +119,15 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { */ function useModule(address _moduleFactory) external { // This if statement is required to be able to add modules from the token proxy contract during deployment - if (ISecurityTokenRegistry(getAddress(Encoder.getKey('securityTokenRegistry'))).isSecurityToken(msg.sender)) { - if (IFeatureRegistry(getAddress(Encoder.getKey('featureRegistry'))).getFeatureStatus("customModulesAllowed")) { - require(getBool(Encoder.getKey('verified', _moduleFactory)) || IOwnable(_moduleFactory).owner() == IOwnable(msg.sender).owner(), - "ModuleFactory must be verified or SecurityToken owner must be ModuleFactory owner"); + if (ISecurityTokenRegistry(getAddress(Encoder.getKey("securityTokenRegistry"))).isSecurityToken(msg.sender)) { + if (IFeatureRegistry(getAddress(Encoder.getKey("featureRegistry"))).getFeatureStatus("customModulesAllowed")) { + require(getBool(Encoder.getKey("verified", _moduleFactory)) || IOwnable(_moduleFactory).owner() == IOwnable(msg.sender).owner(),"ModuleFactory must be verified or SecurityToken owner must be ModuleFactory owner"); } else { - require(getBool(Encoder.getKey('verified', _moduleFactory)), "ModuleFactory must be verified"); + require(getBool(Encoder.getKey("verified", _moduleFactory)), "ModuleFactory must be verified"); } require(_isCompatibleModule(_moduleFactory, msg.sender), "Version should within the compatible range of ST"); - require(getUint(Encoder.getKey('registry',_moduleFactory)) != 0, "ModuleFactory type should not be 0"); - pushArray(Encoder.getKey('reputation', _moduleFactory), msg.sender); + require(getUint(Encoder.getKey("registry",_moduleFactory)) != 0, "ModuleFactory type should not be 0"); + pushArray(Encoder.getKey("reputation", _moduleFactory), msg.sender); emit ModuleUsed(_moduleFactory, msg.sender); } } @@ -147,13 +146,12 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @param _moduleFactory is the address of the module factory to be registered */ function registerModule(address _moduleFactory) external whenNotPausedOrOwner { - if (IFeatureRegistry(getAddress(Encoder.getKey('featureRegistry'))).getFeatureStatus("customModulesAllowed")) { - require(msg.sender == IOwnable(_moduleFactory).owner() || msg.sender == getAddress(Encoder.getKey('owner')), - "msg.sender must be the Module Factory owner or registry curator"); + if (IFeatureRegistry(getAddress(Encoder.getKey("featureRegistry"))).getFeatureStatus("customModulesAllowed")) { + require(msg.sender == IOwnable(_moduleFactory).owner() || msg.sender == getAddress(Encoder.getKey("owner")),"msg.sender must be the Module Factory owner or registry curator"); } else { require(msg.sender == getAddress(Encoder.getKey("owner")), "Only owner allowed to register modules"); } - require(getUint(Encoder.getKey('registry', _moduleFactory)) == 0, "Module factory should not be pre-registered"); + require(getUint(Encoder.getKey("registry", _moduleFactory)) == 0, "Module factory should not be pre-registered"); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); //Enforce type uniqueness uint256 i; @@ -167,9 +165,9 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { require(moduleTypes.length != 0, "Factory must have type"); // NB - here we index by the first type of the module. uint8 moduleType = moduleFactory.getTypes()[0]; - set(Encoder.getKey('registry', _moduleFactory), uint256(moduleType)); - set(Encoder.getKey('moduleListIndex', _moduleFactory), uint256(getArrayAddress(Encoder.getKey('moduleList', uint256(moduleType))).length)); - pushArray(Encoder.getKey('moduleList', uint256(moduleType)), _moduleFactory); + set(Encoder.getKey("registry", _moduleFactory), uint256(moduleType)); + set(Encoder.getKey("moduleListIndex", _moduleFactory), uint256(getArrayAddress(Encoder.getKey("moduleList", uint256(moduleType))).length)); + pushArray(Encoder.getKey("moduleList", uint256(moduleType)), _moduleFactory); emit ModuleRegistered (_moduleFactory, IOwnable(_moduleFactory).owner()); } @@ -178,32 +176,31 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @param _moduleFactory is the address of the module factory to be deleted from the registry */ function removeModule(address _moduleFactory) external whenNotPausedOrOwner { - uint256 moduleType = getUint(Encoder.getKey('registry', _moduleFactory)); + uint256 moduleType = getUint(Encoder.getKey("registry", _moduleFactory)); require(moduleType != 0, "Module factory should be registered"); - require(msg.sender == IOwnable(_moduleFactory).owner() || msg.sender == getAddress(Encoder.getKey('owner')), - "msg.sender must be the Module Factory owner or registry curator"); + require(msg.sender == IOwnable(_moduleFactory).owner() || msg.sender == getAddress(Encoder.getKey("owner")),"msg.sender must be the Module Factory owner or registry curator"); - uint256 index = getUint(Encoder.getKey('moduleListIndex', _moduleFactory)); - uint256 last = getArrayAddress(Encoder.getKey('moduleList', moduleType)).length - 1; - address temp = getArrayAddress(Encoder.getKey('moduleList', moduleType))[last]; + uint256 index = getUint(Encoder.getKey("moduleListIndex", _moduleFactory)); + uint256 last = getArrayAddress(Encoder.getKey("moduleList", moduleType)).length - 1; + address temp = getArrayAddress(Encoder.getKey("moduleList", moduleType))[last]; // pop from array and re-order if (index != last) { // moduleList[moduleType][index] = temp; - setArrayIndexValue(Encoder.getKey('moduleList', moduleType), index, temp); - set(Encoder.getKey('moduleListIndex', temp), index); + setArrayIndexValue(Encoder.getKey("moduleList", moduleType), index, temp); + set(Encoder.getKey("moduleListIndex", temp), index); } - deleteArrayAddress(Encoder.getKey('moduleList', moduleType), last); + deleteArrayAddress(Encoder.getKey("moduleList", moduleType), last); // delete registry[_moduleFactory]; - set(Encoder.getKey('registry', _moduleFactory), uint256(0)); + set(Encoder.getKey("registry", _moduleFactory), uint256(0)); // delete reputation[_moduleFactory]; - setArray(Encoder.getKey('reputation', _moduleFactory), new address[](0)); + setArray(Encoder.getKey("reputation", _moduleFactory), new address[](0)); // delete verified[_moduleFactory]; - set(Encoder.getKey('verified', _moduleFactory), false); + set(Encoder.getKey("verified", _moduleFactory), false); // delete moduleListIndex[_moduleFactory]; - set(Encoder.getKey('moduleListIndex', _moduleFactory), uint256(0)); + set(Encoder.getKey("moduleListIndex", _moduleFactory), uint256(0)); emit ModuleRemoved(_moduleFactory, msg.sender); } @@ -216,8 +213,8 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return bool */ function verifyModule(address _moduleFactory, bool _verified) external onlyOwner { - require(getUint(Encoder.getKey('registry', _moduleFactory)) != uint256(0), "Module factory must be registered"); - set(Encoder.getKey('verified', _moduleFactory), _verified); + require(getUint(Encoder.getKey("registry", _moduleFactory)) != uint256(0), "Module factory must be registered"); + set(Encoder.getKey("verified", _moduleFactory), _verified); emit ModuleVerified(_moduleFactory, _verified); } @@ -278,7 +275,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return address array which contains the list of securityTokens that use that module factory */ function getReputationByFactory(address _factoryAddress) external view returns(address[]) { - return getArrayAddress(Encoder.getKey('reputation', _factoryAddress)); + return getArrayAddress(Encoder.getKey("reputation", _factoryAddress)); } /** @@ -287,7 +284,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return address array that contains the list of addresses of module factory contracts. */ function getModulesByType(uint8 _moduleType) public view returns(address[]) { - return getArrayAddress(Encoder.getKey('moduleList', uint256(_moduleType))); + return getArrayAddress(Encoder.getKey("moduleList", uint256(_moduleType))); } /** @@ -297,17 +294,17 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return address array that contains the list of available addresses of module factory contracts. */ function getModulesByTypeAndToken(uint8 _moduleType, address _securityToken) public view returns (address[]) { - uint256 _len = getArrayAddress(Encoder.getKey('moduleList', uint256(_moduleType))).length; - address[] memory _addressList = getArrayAddress(Encoder.getKey('moduleList', uint256(_moduleType))); - bool _isCustomModuleAllowed = IFeatureRegistry(getAddress(Encoder.getKey('featureRegistry'))).getFeatureStatus("customModulesAllowed"); + uint256 _len = getArrayAddress(Encoder.getKey("moduleList", uint256(_moduleType))).length; + address[] memory _addressList = getArrayAddress(Encoder.getKey("moduleList", uint256(_moduleType))); + bool _isCustomModuleAllowed = IFeatureRegistry(getAddress(Encoder.getKey("featureRegistry"))).getFeatureStatus("customModulesAllowed"); uint256 counter = 0; for (uint256 i = 0; i < _len; i++) { if (_isCustomModuleAllowed) { - if (IOwnable(_addressList[i]).owner() == IOwnable(_securityToken).owner() || getBool(Encoder.getKey('verified', _addressList[i]))) + if (IOwnable(_addressList[i]).owner() == IOwnable(_securityToken).owner() || getBool(Encoder.getKey("verified", _addressList[i]))) if(_isCompatibleModule(_addressList[i], _securityToken)) counter++; } - else if (getBool(Encoder.getKey('verified', _addressList[i]))) { + else if (getBool(Encoder.getKey("verified", _addressList[i]))) { if(_isCompatibleModule(_addressList[i], _securityToken)) counter++; } @@ -316,15 +313,15 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { counter = 0; for (uint256 j = 0; j < _len; j++) { if (_isCustomModuleAllowed) { - if (IOwnable(_addressList[j]).owner() == IOwnable(_securityToken).owner() || getBool(Encoder.getKey('verified', _addressList[j]))) { + if (IOwnable(_addressList[j]).owner() == IOwnable(_securityToken).owner() || getBool(Encoder.getKey("verified", _addressList[j]))) { if(_isCompatibleModule(_addressList[j], _securityToken)) { _tempArray[counter] = _addressList[j]; counter ++; } } } - else if (getBool(Encoder.getKey('verified', _addressList[j]))) { - if(_isCompatibleModule(_addressList[j], _securityToken)) { + else if (getBool(Encoder.getKey("verified", _addressList[j]))) { + if(_isCompatibleModule(_addressList[j], _securityToken)) { _tempArray[counter] = _addressList[j]; counter ++; } @@ -338,10 +335,10 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @param _tokenContract The address of the token contract */ function reclaimERC20(address _tokenContract) external onlyOwner { - require(_tokenContract != address(0)); + require(_tokenContract != address(0), "0x address is invalid"); IERC20 token = IERC20(_tokenContract); uint256 balance = token.balanceOf(address(this)); - require(token.transfer(owner(), balance)); + require(token.transfer(owner(), balance),"token transfer failed"); } /** @@ -363,11 +360,11 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { /** * @notice Stores the contract addresses of other key contracts from the PolymathRegistry */ - function updateFromRegistry() onlyOwner external { - address _polymathRegistry = getAddress(Encoder.getKey('polymathRegistry')); - set(Encoder.getKey('securityTokenRegistry'), IPolymathRegistry(_polymathRegistry).getAddress("SecurityTokenRegistry")); - set(Encoder.getKey('featureRegistry'), IPolymathRegistry(_polymathRegistry).getAddress("FeatureRegistry")); - set(Encoder.getKey('polyToken'), IPolymathRegistry(_polymathRegistry).getAddress("PolyToken")); + function updateFromRegistry() external onlyOwner { + address _polymathRegistry = getAddress(Encoder.getKey("polymathRegistry")); + set(Encoder.getKey("securityTokenRegistry"), IPolymathRegistry(_polymathRegistry).getAddress("SecurityTokenRegistry")); + set(Encoder.getKey("featureRegistry"), IPolymathRegistry(_polymathRegistry).getAddress("FeatureRegistry")); + set(Encoder.getKey("polyToken"), IPolymathRegistry(_polymathRegistry).getAddress("PolyToken")); } /** diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index 8f2229b59..9286a1a7f 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -108,7 +108,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { - require(msg.sender == owner()); + require(msg.sender == owner(),"sender must be owner"); _; } @@ -156,7 +156,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _owner is the owner of the STR */ function initialize(address _polymathRegistry, address _STFactory, uint256 _stLaunchFee, uint256 _tickerRegFee, address _polyToken, address _owner) payable external { - require(!getBool(Encoder.getKey("initialised"))); + require(!getBool(Encoder.getKey("initialised")),"already initialized"); require(_STFactory != address(0) && _polyToken != address(0) && _owner != address(0) && _polymathRegistry != address(0), "Invalid address"); require(_stLaunchFee != 0 && _tickerRegFee != 0, "Fees should not be 0"); set(Encoder.getKey("polyToken"), _polyToken); @@ -202,7 +202,16 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { /** * @notice Internal - Sets the details of the ticker */ - function _addTicker(address _owner, string _ticker, string _tokenName, uint256 _registrationDate, uint256 _expiryDate, bool _status, bool _fromAdmin, uint256 _fee) internal { + function _addTicker( + address _owner, + string _ticker, + string _tokenName, + uint256 _registrationDate, + uint256 _expiryDate, + bool _status, + bool _fromAdmin, + uint256 _fee + ) internal { _setTickerOwnership(_owner, _ticker); _storeTickerDetails(_ticker, _owner, _registrationDate, _expiryDate, _tokenName, _status); emit RegisterTicker(_owner, _ticker, _tokenName, _registrationDate, _expiryDate, _fromAdmin, _fee); @@ -218,7 +227,14 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _expiryDate is the expiry date for the ticker * @param _status is the token deployment status */ - function modifyTicker(address _owner, string _ticker, string _tokenName, uint256 _registrationDate, uint256 _expiryDate, bool _status) external onlyOwner { + function modifyTicker( + address _owner, + string _ticker, + string _tokenName, + uint256 _registrationDate, + uint256 _expiryDate, + bool _status + ) external onlyOwner { require(bytes(_ticker).length > 0 && bytes(_ticker).length <= 10, "Ticker length range (0,10]"); require(_expiryDate != 0 && _registrationDate != 0, "Dates should not be 0"); require(_registrationDate <= _expiryDate, "Registration date should < expiry date"); @@ -230,7 +246,14 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { /** * @notice Internal -- Modifies the ticker details. */ - function _modifyTicker(address _owner, string _ticker, string _tokenName, uint256 _registrationDate, uint256 _expiryDate, bool _status) internal { + function _modifyTicker( + address _owner, + string _ticker, + string _tokenName, + uint256 _registrationDate, + uint256 _expiryDate, + bool _status + ) internal { address currentOwner = _tickerOwner(_ticker); if (currentOwner != address(0)) { _deleteTickerOwnership(currentOwner, _ticker); @@ -302,7 +325,14 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { /** * @notice Internal - Stores the ticker details */ - function _storeTickerDetails(string _ticker, address _owner, uint256 _registrationDate, uint256 _expiryDate, string _tokenName, bool _status) internal { + function _storeTickerDetails( + string _ticker, + address _owner, + uint256 _registrationDate, + uint256 _expiryDate, + string _tokenName, + bool _status + ) internal { bytes32 key = Encoder.getKey("registeredTickers_owner", _ticker); if (getAddress(key) != _owner) set(key, _owner); @@ -360,7 +390,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { */ function changeExpiryLimit(uint256 _newExpiry) external onlyOwner { require(_newExpiry >= 1 days, "Expiry should >= 1 day"); - bytes32 key = Encoder.getKey('expiryLimit'); + bytes32 key = Encoder.getKey("expiryLimit"); emit ChangeExpiryLimit(getUint(key), _newExpiry); set(key, _newExpiry); } @@ -370,17 +400,17 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _owner is the address which owns the list of tickers */ function getTickersByOwner(address _owner) external view returns(bytes32[]) { - uint counter = 0; - // accessing the data structure userTotickers[_owner].length - bytes32[] memory tickers = getArrayBytes32(Encoder.getKey("userToTickers", _owner)); - bytes32[] memory tempList = new bytes32[](tickers.length); - for (uint i = 0; i < tickers.length; i++) { - string memory ticker = Util.bytes32ToString(tickers[i]); - if (getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || _tickerStatus(ticker)) { - tempList[counter] = tickers[i]; - counter ++; - } - } + uint counter = 0; + // accessing the data structure userTotickers[_owner].length + bytes32[] memory tickers = getArrayBytes32(Encoder.getKey("userToTickers", _owner)); + bytes32[] memory tempList = new bytes32[](tickers.length); + for (uint i = 0; i < tickers.length; i++) { + string memory ticker = Util.bytes32ToString(tickers[i]); + if (getUint(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || _tickerStatus(ticker)) { + tempList[counter] = tickers[i]; + counter ++; + } + } return tempList; } @@ -598,25 +628,25 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @notice Sets the ticker registration fee in POLY tokens. Only Polymath. * @param _tickerRegFee is the registration fee in POLY tokens (base 18 decimals) */ - function changeTickerRegistrationFee(uint256 _tickerRegFee) external onlyOwner { - bytes32 key = Encoder.getKey('tickerRegFee'); + function changeTickerRegistrationFee(uint256 _tickerRegFee) external onlyOwner { + bytes32 key = Encoder.getKey("tickerRegFee"); uint256 fee = getUint(key); require(fee != _tickerRegFee); emit ChangeTickerRegistrationFee(fee, _tickerRegFee); set(key, _tickerRegFee); - } + } /** * @notice Sets the ticker registration fee in POLY tokens. Only Polymath. * @param _stLaunchFee is the registration fee in POLY tokens (base 18 decimals) */ - function changeSecurityLaunchFee(uint256 _stLaunchFee) external onlyOwner { - bytes32 key = Encoder.getKey('stLaunchFee'); + function changeSecurityLaunchFee(uint256 _stLaunchFee) external onlyOwner { + bytes32 key = Encoder.getKey("stLaunchFee"); uint256 fee = getUint(key); require(fee != _stLaunchFee); emit ChangeSecurityLaunchFee(fee, _stLaunchFee); set(key, _stLaunchFee); - } + } /** * @notice Reclaims all ERC20Basic compatible tokens From 308f9924f63e1cba80795e49e15c5423e37ef08c Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 5 Oct 2018 17:41:05 -0300 Subject: [PATCH 095/142] fixed linter errors and typos in SecurityToken --- contracts/libraries/TokenLib.sol | 41 +++++++------ contracts/tokens/STFactory.sol | 17 ++++-- contracts/tokens/SecurityToken.sol | 96 ++++++++++++++++++------------ 3 files changed, 94 insertions(+), 60 deletions(-) diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index af4b98fa6..36da57ef3 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -33,9 +33,9 @@ library TokenLib { uint256 investorCount; } - // Emit when Module get archived from the securityToken + // Emit when Module is archived from the SecurityToken event ModuleArchived(uint8[] _types, address _module, uint256 _timestamp); - // Emit when Module get unarchived from the securityToken + // Emit when Module is unarchived from the SecurityToken event ModuleUnarchived(uint8[] _types, address _module, uint256 _timestamp); /** @@ -62,13 +62,13 @@ library TokenLib { } /** - * @notice Validate permissions with PermissionManager if it exists, If no Permission return false - * @dev Note that IModule withPerm will allow ST owner all permissions anyway + * @notice Validate permissions with PermissionManager if it exists. If there's no permission return false + * @dev Note that IModule withPerm will allow ST owner all permissions by default * @dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions) - * @param _modules storage data - * @param _delegate address of delegate - * @param _module address of PermissionManager module - * @param _perm the permissions + * @param _modules is the modules to check permissions on + * @param _delegate is the address of the delegate + * @param _module is the address of the PermissionManager module + * @param _perm is the permissions data * @return success */ function checkPermission(address[] storage _modules, address _delegate, address _module, bytes32 _perm) public view returns(bool) { @@ -86,10 +86,10 @@ library TokenLib { } /** - * @notice Queries value at a defined checkpoint + * @notice Queries a value at a defined checkpoint * @param _checkpoints is array of Checkpoint objects - * @param _checkpointId Checkpoint ID to query - * @param _currentValue Current value of checkpoint + * @param _checkpointId is the Checkpoint ID to query + * @param _currentValue is the Current value of checkpoint * @return uint256 */ function getValueAt(Checkpoint[] storage _checkpoints, uint256 _checkpointId, uint256 _currentValue) public view returns(uint256) { @@ -127,9 +127,9 @@ library TokenLib { } /** - * @notice store the changes to the checkpoint objects - * @param _checkpoints the affected checkpoint object array - * @param _newValue the new value that needs to be stored + * @notice Stores the changes to the checkpoint objects + * @param _checkpoints is the affected checkpoint object array + * @param _newValue is the new value that needs to be stored */ function adjustCheckpoints(TokenLib.Checkpoint[] storage _checkpoints, uint256 _newValue, uint256 _currentCheckpointId) public { //No checkpoints set yet @@ -158,7 +158,14 @@ library TokenLib { * @param _balanceTo balance of the _to address * @param _balanceFrom balance of the _from address */ - function adjustInvestorCount(InvestorDataStorage storage _investorData, address _from, address _to, uint256 _value, uint256 _balanceTo, uint256 _balanceFrom) public { + function adjustInvestorCount( + InvestorDataStorage storage _investorData, + address _from, + address _to, + uint256 _value, + uint256 _balanceTo, + uint256 _balanceFrom + ) public { if ((_value == 0) || (_from == _to)) { return; } @@ -180,8 +187,8 @@ library TokenLib { /** * @notice removes addresses with zero balances from the investors list - * @param _investorData Date releated to investor metrics - * @param _index Index in investor list + * @param _investorData is the date related to investor metrics + * @param _index is the index in investor list * NB - pruning this list will mean you may not be able to iterate over investors on-chain as of a historical checkpoint */ function pruneInvestors(InvestorDataStorage storage _investorData, uint256 _index) public { diff --git a/contracts/tokens/STFactory.sol b/contracts/tokens/STFactory.sol index 4277a8f29..85153e816 100644 --- a/contracts/tokens/STFactory.sol +++ b/contracts/tokens/STFactory.sol @@ -4,7 +4,7 @@ import "./SecurityToken.sol"; import "../interfaces/ISTFactory.sol"; /** - * @title Proxy for deploying Security Token v1 + * @title Proxy for deploying SecurityToken instances */ contract STFactory is ISTFactory { @@ -15,11 +15,18 @@ contract STFactory is ISTFactory { } /** - * @notice deploys the token and adds default modules like permission manager and transfer manager. - * Future versions of the proxy can attach different modules or pass some other paramters. + * @notice deploys the token and adds default modules like the GeneralTransferManager. + * Future versions of the proxy can attach different modules or pass different parameters. */ - function deployToken(string _name, string _symbol, uint8 _decimals, string _tokenDetails, address _issuer, bool _divisible, address _polymathRegistry) - external returns (address) { + function deployToken( + string _name, + string _symbol, + uint8 _decimals, + string _tokenDetails, + address _issuer, + bool _divisible, + address _polymathRegistry + ) external returns (address) { address newSecurityTokenAddress = new SecurityToken( _name, _symbol, diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 2b021c372..3458f7a4c 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -29,7 +29,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr TokenLib.InvestorDataStorage investorData; - // Use to hold the version + // Used to hold the semantic version data struct SemanticVersion { uint8 major; uint8 minor; @@ -38,7 +38,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr SemanticVersion securityTokenVersion; - // off-chain hash + // off-chain data string public tokenDetails; uint8 constant PERMISSION_KEY = 1; @@ -52,10 +52,10 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // Value of current checkpoint uint256 public currentCheckpointId; - // Use to temporarily halt all transactions + // Used to temporarily halt all transactions bool public transfersFrozen; - // Use to permanently halt all minting + // Used to permanently halt all minting bool public mintingFrozen; // Use to permanently halt controller actions @@ -166,7 +166,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice Revert if called by account which is not a controller + * @notice Revert if called by an account which is not a controller */ modifier onlyController() { require(msg.sender == controller, "Not controller"); @@ -180,7 +180,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _symbol Symbol of the Token * @param _decimals Decimals for the securityToken * @param _granularity granular level of the token - * @param _tokenDetails Details of the token that are stored off-chain (IPFS hash) + * @param _tokenDetails Details of the token that are stored off-chain * @param _polymathRegistry Contract address of the polymath registry */ constructor ( @@ -203,15 +203,13 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice Function used to attach a module to the security token + * @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. - * @dev You are allowed to add a new moduleType if: - * @dev - there is no existing module of that type yet added - * @dev - the last member of the module list is replacable * @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 module. (WIP) + * @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, @@ -219,7 +217,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr uint256 _maxCost, uint256 _budget ) external onlyOwner nonReentrant { - //Check that module exists in registry - will throw otherwise + //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(); @@ -289,6 +287,10 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr delete modulesToData[_module]; } + /** + * @notice Internal - Removes a module attached to the SecurityToken by index + * @param _module address of module to remove + */ function _removeModuleWithIndex(uint8 _type, uint256 _index) internal { uint256 length = modules[_type].length; modules[_type][_index] = modules[_type][length - 1]; @@ -306,7 +308,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice Returns module list for a module type + * @notice Returns the data associated to a module * @param _module address of the module * @return bytes32 name * @return address module address @@ -316,14 +318,14 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr */ function getModule(address _module) external view returns (bytes32, address, address, bool, uint8[]) { return (modulesToData[_module].name, - modulesToData[_module].module, - modulesToData[_module].moduleFactory, - modulesToData[_module].isArchived, - modulesToData[_module].moduleTypes); + modulesToData[_module].module, + modulesToData[_module].moduleFactory, + modulesToData[_module].isArchived, + modulesToData[_module].moduleTypes); } /** - * @notice returns module list for a module name + * @notice returns a list of modules that match the provided name * @param _name name of the module * @return address[] list of modules with this name */ @@ -332,7 +334,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice returns module list for a module type + * @notice returns a list of modules that match the provided module type * @param _type type of the module * @return address[] list of modules with this type */ @@ -366,7 +368,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice change the tokenDetails + * @notice updates the tokenDetails associated with the token * @param _newTokenDetails New token details */ function updateTokenDetails(string _newTokenDetails) external onlyOwner { @@ -409,7 +411,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice gets length of investors array + * @notice returns an array of investors * NB - this length may differ from investorCount if list has not been pruned of zero balance investors * @return length */ @@ -418,17 +420,17 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice gets the investor count + * @notice returns the investor count */ function getInvestorCount() external view returns(uint256) { return investorData.investorCount; } /** - * @notice freeze transfers + * @notice freezes transfers */ function freezeTransfers() external onlyOwner { - require(!transfersFrozen); + require(!transfersFrozen, "transfers already frozen"); transfersFrozen = true; emit FreezeTransfers(true, now); } @@ -437,20 +439,20 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice unfreeze transfers */ function unfreezeTransfers() external onlyOwner { - require(transfersFrozen); + require(transfersFrozen, "transfer are not fronzen"); transfersFrozen = false; emit FreezeTransfers(false, now); } /** - * @notice adjust totalsupply at checkpoint after minting or burning tokens + * @notice Internal - adjusts totalSupply at checkpoint after minting or burning tokens */ function _adjustTotalSupplyCheckpoints() internal { TokenLib.adjustCheckpoints(checkpointTotalSupply, totalSupply(), currentCheckpointId); } /** - * @notice adjust token holder balance at checkpoint after a token transfer + * @notice Internal - adjusts token holder balance at checkpoint after a token transfer * @param _investor address of the token holder affected */ function _adjustBalanceCheckpoints(address _investor) internal { @@ -505,6 +507,14 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return true; } + /** + * @notice Updates internal variables when performing a transfer + * @param _from sender of transfer + * @param _to receiver of transfer + * @param _value value of transfer + * @param _data data to indicate validation + * @return bool success + */ function _updateTransfer(address _from, address _to, uint256 _value, bytes _data) internal returns(bool) { _adjustInvestorCount(_from, _to, _value); _adjustBalanceCheckpoints(_from); @@ -522,7 +532,13 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _isTransfer whether transfer is being executed * @return bool */ - function _verifyTransfer(address _from, address _to, uint256 _value, bytes _data, bool _isTransfer) internal checkGranularity(_value) returns (bool) { + function _verifyTransfer( + address _from, + address _to, + uint256 _value, + bytes _data, + bool _isTransfer + ) internal checkGranularity(_value) returns (bool) { if (!transfersFrozen) { if (modules[TRANSFER_KEY].length == 0) { return true; @@ -555,7 +571,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice validate transfer with TransferManager module if it exists + * @notice validates a transfer with a TransferManager module if it exists * @dev TransferManager module has a key of 2 * @param _from sender of transfer * @param _to receiver of transfer @@ -595,7 +611,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _data data to indicate validation * @return success */ - function mintWithData(address _investor, uint256 _value, bytes _data) public onlyModuleOrOwner(MINT_KEY) isMintingAllowed() returns (bool success) { + function mintWithData( + address _investor, + uint256 _value, + bytes _data + ) public onlyModuleOrOwner(MINT_KEY) isMintingAllowed() returns (bool success) { require(_investor != address(0), "Investor is 0"); require(_updateTransfer(address(0), _investor, _value, _data), "Transfer not valid"); _adjustTotalSupplyCheckpoints(); @@ -650,7 +670,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _value No. of tokens that get burned * @param _data data to indicate validation */ - function burnWithData(uint256 _value, bytes _data) onlyModule(BURN_KEY) public { + function burnWithData(uint256 _value, bytes _data) public onlyModule(BURN_KEY) { require(_burn(msg.sender, _value, _data), "Burn not valid"); } @@ -660,7 +680,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _value No. of tokens that get burned * @param _data data to indicate validation */ - function burnFromWithData(address _from, uint256 _value, bytes _data) onlyModule(BURN_KEY) public { + function burnFromWithData(address _from, uint256 _value, bytes _data) public onlyModule(BURN_KEY) { require(_value <= allowed[_from][msg.sender], "Value too high"); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); require(_burn(_from, _value, _data), "Burn not valid"); @@ -707,11 +727,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice Use by the issuer ot set the controller addresses + * @notice Used by the issuer to set the controller addresses * @param _controller address of the controller */ function setController(address _controller) public onlyOwner { - require(!controllerDisabled); + require(!controllerDisabled,"Controller functions are disabled"); emit SetController(controller, _controller); controller = _controller; } @@ -721,14 +741,14 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @dev enabled via feature switch "disableControllerAllowed" */ function disableController() external isEnabled("disableControllerAllowed") onlyOwner { - require(!controllerDisabled); + require(!controllerDisabled,"Controller functions are disabled"); controllerDisabled = true; delete controller; emit DisableController(now); } /** - * @notice Use by a controller to execute a foced transfer + * @notice Use by a controller to execute a forced transfer * @param _from address from which to take tokens * @param _to address where to send tokens * @param _value amount of tokens to transfer @@ -746,7 +766,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice Use by a controller to execute a foced burn + * @notice Use by a controller to execute a forced burn * @param _from address from which to take tokens * @param _value amount of tokens to transfer * @param _data data to indicate validation @@ -758,7 +778,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice Use to get the version of the securityToken + * @notice Returns the version of the SecurityToken */ function getVersion() external view returns(uint8[]) { uint8[] memory _version = new uint8[](3); From 5bf40c5db2808a66429c9a2508a13edb7b72f8a0 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 5 Oct 2018 18:11:22 -0300 Subject: [PATCH 096/142] fixed linter errors is STO modules --- .../modules/Burn/TrackedRedemptionFactory.sol | 2 +- .../modules/Checkpoint/DividendCheckpoint.sol | 46 +++++++++---------- .../Checkpoint/EtherDividendCheckpoint.sol | 12 ++--- .../GeneralPermissionManager.sol | 2 +- contracts/modules/STO/USDTieredSTO.sol | 13 +++--- contracts/tokens/SecurityToken.sol | 1 - 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/contracts/modules/Burn/TrackedRedemptionFactory.sol b/contracts/modules/Burn/TrackedRedemptionFactory.sol index 6611b2875..c1a487e65 100644 --- a/contracts/modules/Burn/TrackedRedemptionFactory.sol +++ b/contracts/modules/Burn/TrackedRedemptionFactory.sol @@ -93,7 +93,7 @@ contract TrackedRedemptionFactory is ModuleFactory { * @notice Get the tags related to the module factory */ function getTags() external view returns(bytes32[]) { - bytes32[] memory availableTags = new bytes32[](2); + bytes32[] memory availableTags = new bytes32[](2); availableTags[0] = "Redemption"; availableTags[1] = "Tracked"; return availableTags; diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 1385637bc..a097a659b 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -17,19 +17,19 @@ contract DividendCheckpoint is ICheckpoint, Module { bytes32 public constant DISTRIBUTE = "DISTRIBUTE"; struct Dividend { - uint256 checkpointId; - uint256 created; // Time at which the dividend was created - uint256 maturity; // Time after which dividend can be claimed - set to 0 to bypass - uint256 expiry; // Time until which dividend can be claimed - after this time any remaining amount can be withdrawn by issuer - set to very high value to bypass - uint256 amount; // Dividend amount in WEI - uint256 claimedAmount; // Amount of dividend claimed so far - uint256 totalSupply; // Total supply at the associated checkpoint (avoids recalculating this) - bool reclaimed; // True if expiry has passed and issuer has reclaimed remaining dividend - uint256 dividendWithheld; - uint256 dividendWithheldReclaimed; - mapping (address => bool) claimed; // List of addresses which have claimed dividend - mapping (address => bool) dividendExcluded; // List of addresses which cannot claim dividends - bytes32 name; // Name/title - used for identification + uint256 checkpointId; + uint256 created; // Time at which the dividend was created + uint256 maturity; // Time after which dividend can be claimed - set to 0 to bypass + uint256 expiry; // Time until which dividend can be claimed - after this time any remaining amount can be withdrawn by issuer - set to very high value to bypass + uint256 amount; // Dividend amount in WEI + uint256 claimedAmount; // Amount of dividend claimed so far + uint256 totalSupply; // Total supply at the associated checkpoint (avoids recalculating this) + bool reclaimed; // True if expiry has passed and issuer has reclaimed remaining dividend + uint256 dividendWithheld; + uint256 dividendWithheldReclaimed; + mapping (address => bool) claimed; // List of addresses which have claimed dividend + mapping (address => bool) dividendExcluded; // List of addresses which cannot claim dividends + bytes32 name; // Name/title - used for identification } // List of all dividends @@ -198,15 +198,15 @@ contract DividendCheckpoint is ICheckpoint, Module { } } - uint256[] memory index = new uint256[](counter); - counter = 0; - for(uint256 j = 0; j < dividends.length; j++) { - if (dividends[j].checkpointId == _checkpointId) { - index[counter] = j; - counter++; - } - } - return index; + uint256[] memory index = new uint256[](counter); + counter = 0; + for(uint256 j = 0; j < dividends.length; j++) { + if (dividends[j].checkpointId == _checkpointId) { + index[counter] = j; + counter++; + } + } + return index; } /** @@ -216,7 +216,7 @@ contract DividendCheckpoint is ICheckpoint, Module { function withdrawWithholding(uint256 _dividendIndex) external; /** - * @notice Return the permissions flag that are associated with STO + * @notice Return the permissions flag that are associated with this module * @return bytes32 array */ function getPermissions() public view returns(bytes32[]) { diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol index d8ecb2e9a..0d5e3fbf2 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol @@ -141,13 +141,13 @@ contract EtherDividendCheckpoint is DividendCheckpoint { uint256 claimAfterWithheld = claim.sub(withheld); if (claimAfterWithheld > 0) { if (_payee.send(claimAfterWithheld)) { - _dividend.claimedAmount = _dividend.claimedAmount.add(claim); - _dividend.dividendWithheld = _dividend.dividendWithheld.add(withheld); - investorWithheld[_payee] = investorWithheld[_payee].add(withheld); - emit EtherDividendClaimed(_payee, _dividendIndex, claim, withheld); + _dividend.claimedAmount = _dividend.claimedAmount.add(claim); + _dividend.dividendWithheld = _dividend.dividendWithheld.add(withheld); + investorWithheld[_payee] = investorWithheld[_payee].add(withheld); + emit EtherDividendClaimed(_payee, _dividendIndex, claim, withheld); } else { - _dividend.claimed[_payee] = false; - emit EtherDividendClaimFailed(_payee, _dividendIndex, claim, withheld); + _dividend.claimed[_payee] = false; + emit EtherDividendClaimFailed(_payee, _dividendIndex, claim, withheld); } } } diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 849fe0094..563778b12 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -137,7 +137,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { uint8 i = 0; for (i = 0; i < allDelegates.length; i++) { if (perms[_module][allDelegates[i]][_perm]) { - counter++; + counter++; } } address[] memory allDelegatesWithPerm = new address[](counter); diff --git a/contracts/modules/STO/USDTieredSTO.sol b/contracts/modules/STO/USDTieredSTO.sol index 86687eb58..5675ad0f4 100644 --- a/contracts/modules/STO/USDTieredSTO.sol +++ b/contracts/modules/STO/USDTieredSTO.sol @@ -447,22 +447,23 @@ contract USDTieredSTO is ISTO, ReentrancyGuard { uint256 spentUSD; uint256 tierSpentUSD; uint256 tierPurchasedTokens; + uint256 investedUSD = _investedUSD; // Check whether there are any remaining discounted tokens if ((_fundRaiseType == FundRaiseType.POLY) && (tokensPerTierDiscountPoly[_tier] > mintedPerTierDiscountPoly[_tier])) { uint256 discountRemaining = tokensPerTierDiscountPoly[_tier].sub(mintedPerTierDiscountPoly[_tier]); uint256 totalRemaining = tokensPerTierTotal[_tier].sub(mintedPerTierTotal[_tier]); if (totalRemaining < discountRemaining) - (spentUSD, tierPurchasedTokens) = _purchaseTier(_beneficiary, ratePerTierDiscountPoly[_tier], totalRemaining, _investedUSD, _tier); + (spentUSD, tierPurchasedTokens) = _purchaseTier(_beneficiary, ratePerTierDiscountPoly[_tier], totalRemaining, investedUSD, _tier); else - (spentUSD, tierPurchasedTokens) = _purchaseTier(_beneficiary, ratePerTierDiscountPoly[_tier], discountRemaining, _investedUSD, _tier); - _investedUSD = _investedUSD.sub(spentUSD); + (spentUSD, tierPurchasedTokens) = _purchaseTier(_beneficiary, ratePerTierDiscountPoly[_tier], discountRemaining, investedUSD, _tier); + investedUSD = investedUSD.sub(spentUSD); mintedPerTierDiscountPoly[_tier] = mintedPerTierDiscountPoly[_tier].add(tierPurchasedTokens); mintedPerTier[uint8(FundRaiseType.POLY)][_tier] = mintedPerTier[uint8(FundRaiseType.POLY)][_tier].add(tierPurchasedTokens); mintedPerTierTotal[_tier] = mintedPerTierTotal[_tier].add(tierPurchasedTokens); } // Now, if there is any remaining USD to be invested, purchase at non-discounted rate - if ((_investedUSD > 0) && (tokensPerTierTotal[_tier].sub(mintedPerTierTotal[_tier]) > 0)) { - (tierSpentUSD, tierPurchasedTokens) = _purchaseTier(_beneficiary, ratePerTier[_tier], tokensPerTierTotal[_tier].sub(mintedPerTierTotal[_tier]), _investedUSD, _tier); + if ((investedUSD > 0) && (tokensPerTierTotal[_tier].sub(mintedPerTierTotal[_tier]) > 0)) { + (tierSpentUSD, tierPurchasedTokens) = _purchaseTier(_beneficiary, ratePerTier[_tier], tokensPerTierTotal[_tier].sub(mintedPerTierTotal[_tier]), investedUSD, _tier); spentUSD = spentUSD.add(tierSpentUSD); mintedPerTier[uint8(_fundRaiseType)][_tier] = mintedPerTier[uint8(_fundRaiseType)][_tier].add(tierPurchasedTokens); mintedPerTierTotal[_tier] = mintedPerTierTotal[_tier].add(tierPurchasedTokens); @@ -551,7 +552,7 @@ contract USDTieredSTO is ISTO, ReentrancyGuard { * @return uint256 Value in ETH or POLY */ function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) { - uint256 rate = getRate(_fundRaiseType); + uint256 rate = getRate(_fundRaiseType); return DecimalMath.div(_amount, rate); } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 3458f7a4c..dde865fa8 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -289,7 +289,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr /** * @notice Internal - Removes a module attached to the SecurityToken by index - * @param _module address of module to remove */ function _removeModuleWithIndex(uint8 _type, uint256 _index) internal { uint256 length = modules[_type].length; From 018e81da164151ffc2b352a02cc3b2c8aa7a6882 Mon Sep 17 00:00:00 2001 From: satyam Date: Sun, 7 Oct 2018 13:28:28 +0530 Subject: [PATCH 097/142] remove more cruft --- test/b_capped_sto.js | 20 +--- test/c_checkpoints.js | 3 - test/d_count_transfer_manager.js | 27 +---- test/e_erc20_dividends.js | 4 +- test/f_ether_dividends.js | 4 +- test/g_general_permission_manager.js | 54 +--------- test/h_general_transfer_manager.js | 4 +- test/helpers/createInstances.js | 93 ++++++++++------ test/i_Issuance.js | 154 ++++++--------------------- 9 files changed, 106 insertions(+), 257 deletions(-) diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 6a788086b..33fc5f6a6 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -2,13 +2,12 @@ import latestTime from "./helpers/latestTime"; import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeModuleCall } from "./helpers/encodeCall"; -import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployGPMAndVerifyed } from "./helpers/createInstances"; import { catchRevert } from "./helpers/exceptions"; const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); @@ -129,17 +128,8 @@ contract("CappedSTO", accounts => { ] = instances; // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + // STEP 6: Deploy the CappedSTOFactory I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); @@ -152,10 +142,6 @@ contract("CappedSTO", accounts => { // STEP 7: Register the Modules with the ModuleRegistry contract - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (C) : Register the STOFactory await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index 0c5fa84f6..6a08b6dea 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -60,9 +60,6 @@ contract("Checkpoints", accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; - before(async () => { // Accounts setup account_polymath = accounts[0]; diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 07559d189..3bf785a5d 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -2,7 +2,7 @@ import latestTime from "./helpers/latestTime"; import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeModuleCall } from "./helpers/encodeCall"; -import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployCountTMAndVerifyed } from "./helpers/createInstances"; import { catchRevert } from "./helpers/exceptions"; const SecurityToken = artifacts.require("./SecurityToken.sol"); @@ -100,30 +100,9 @@ contract("CountTransferManager", accounts => { ] = instances; // STEP 2: Deploy the CountTransferManager - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_CountTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CountTransferManagerFactory contract was not deployed" - ); - + [I_CountTransferManagerFactory] = await deployCountTMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // STEP 3: Deploy Paid the CountTransferManager - P_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, { - from: account_polymath - }); - assert.notEqual( - P_CountTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CountTransferManagerFactory contract was not deployed" - ); - - // (C) : Register the CountTransferManagerFactory - await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid CountTransferManagerFactory - await I_MRProxied.registerModule(P_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_CountTransferManagerFactory.address, true, { from: account_polymath }); + [P_CountTransferManagerFactory] = await deployCountTMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); // Printing all the contract addresses console.log(` diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 07af23bdb..ac690b8ae 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -98,8 +98,8 @@ contract("ERC20DividendCheckpoint", accounts => { I_STRProxied ] = instances; - [P_ERC20DividendCheckpointFactory] = await deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, web3.utils.toWei("500", "ether")); - [I_ERC20DividendCheckpointFactory] = await deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); + [P_ERC20DividendCheckpointFactory] = await deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); + [I_ERC20DividendCheckpointFactory] = await deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index d4b9a3724..46d5d6a35 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -98,8 +98,8 @@ contract("EtherDividendCheckpoint", accounts => { I_STRProxied ] = instances; - [P_EtherDividendCheckpointFactory] = await deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, web3.utils.toWei("500", "ether")); - [P_EtherDividendCheckpointFactory] = await deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); + [P_EtherDividendCheckpointFactory] = await deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); + [I_EtherDividendCheckpointFactory] = await deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 1bc9dcb71..417624516 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -5,12 +5,10 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed } from "./helpers/createInstances"; -const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const DummySTO = artifacts.require("./DummySTO.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); @@ -113,55 +111,11 @@ contract("GeneralPermissionManager", accounts => { // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // STEP 6: Deploy the GeneralDelegateManagerFactory - - P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new( - I_PolyToken.address, - web3.utils.toWei("500", "ether"), - 0, - 0, - { from: account_polymath } - ); - - assert.notEqual( - P_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - + [P_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); // STEP 7: Deploy the DummySTOFactory - - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" - ); - - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the Paid GeneralDelegateManagerFactory - await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index d5a8b3e03..bc83f7ec5 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -112,8 +112,8 @@ contract("GeneralTransferManager", accounts => { I_STRProxied ] = instances; - [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); - [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, 0); + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 655c9ebc1..feabbb01f 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -4,6 +4,7 @@ const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); +const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); @@ -13,6 +14,7 @@ const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); const STFactory = artifacts.require("./STFactory.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); +const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const PolyToken = artifacts.require("./PolyToken.sol"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); @@ -23,6 +25,7 @@ const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Contract Instance Declaration let I_EtherDividendCheckpointFactory; +let I_CountTransferManagerFactory; let I_ERC20DividendCheckpointFactory; let I_GeneralPermissionManagerFactory; let I_GeneralTransferManagerFactory; @@ -31,6 +34,7 @@ let I_ModuleRegistryProxy; let I_ModuleRegistry; let I_FeatureRegistry; let I_SecurityTokenRegistry; +let I_CappedSTOFactory; let I_SecurityToken; let I_DummySTOFactory; let I_PolyToken; @@ -46,6 +50,8 @@ const initRegFee = web3.utils.toWei("250"); const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; const MRProxyParameters = ["address", "address"]; +/// Function use to launch the polymath ecossystem. + export async function setUpPolymathNetwork(account_polymath, token_owner) { // ----------- POLYMATH NETWORK Configuration ------------ // Step 1: Deploy the PolyToken and PolymathRegistry @@ -68,15 +74,6 @@ export async function setUpPolymathNetwork(account_polymath, token_owner) { return mergeReturn(tempArray); } -function mergeReturn(returnData) { - let returnArray = new Array(); - for (let i = 0; i < returnData.length; i++) { - for (let j = 0; j < returnData[i].length; j++) { - returnArray.push(returnData[i][j]); - } - } - return returnArray; -} async function deployPolyRegistryAndPolyToken(account_polymath, token_owner) { // Step 0: Deploy the PolymathRegistry @@ -166,10 +163,13 @@ async function registerGTM(account_polymath) { await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); } +async function registerAndVerifyByMR(factoryAdrress, owner, mr) { + await mr.registerModule(factoryAdrress, { from: owner }); + await mr.verifyModule(factoryAdrress, true, { from: owner }); +} - -export async function deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); +export async function deployGPMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), @@ -178,46 +178,37 @@ export async function deployGPMAndVerifyed(account_polymath, I_MRProxied, I_Poly ); // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - + await registerAndVerifyByMR(I_GeneralPermissionManagerFactory.address, accountPolymath, MRProxyInstance); return new Array(I_GeneralPermissionManagerFactory); } -export async function deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); +export async function deployDummySTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_DummySTOFactory = await DummySTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( I_DummySTOFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "DummySTOFactory contract was not deployed" ); - - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - + await registerAndVerifyByMR(I_DummySTOFactory.address, accountPolymath, MRProxyInstance); return new Array(I_DummySTOFactory); } -export async function deployERC20DividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { - I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); +export async function deployERC20DividendAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( I_ERC20DividendCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "ERC20DividendCheckpointFactory contract was not deployed" ); - - await I_MRProxied.registerModule(I_ERC20DividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ERC20DividendCheckpointFactory.address, true, { from: account_polymath }); - + await registerAndVerifyByMR(I_ERC20DividendCheckpointFactory.address, accountPolymath, MRProxyInstance); return new Array(I_ERC20DividendCheckpointFactory); } - -export async function deployEtherDividendAndVerifyed(account_polymath, I_MRProxied, I_PolyToken, setupCost) { - I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(I_PolyToken.address, setupCost, 0, 0, { from: account_polymath }); +export async function deployEtherDividendAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( I_EtherDividendCheckpointFactory.address.valueOf(), @@ -225,8 +216,44 @@ export async function deployEtherDividendAndVerifyed(account_polymath, I_MRProxi "EtherDividendCheckpointFactory contract was not deployed" ); - await I_MRProxied.registerModule(I_EtherDividendCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_EtherDividendCheckpointFactory.address, true, { from: account_polymath }); - + await registerAndVerifyByMR(I_EtherDividendCheckpointFactory.address, accountPolymath, MRProxyInstance); return new Array(I_EtherDividendCheckpointFactory); +} + +export async function deployCountTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_CountTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CountTransferManagerFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_CountTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_CountTransferManagerFactory); +} + +export async function deployCappedSTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_CappedSTOFactory = await CappedSTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_CappedSTOFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_CappedSTOFactory); + +} + +/// Helper function +function mergeReturn(returnData) { + let returnArray = new Array(); + for (let i = 0; i < returnData.length; i++) { + for (let j = 0; j < returnData[i].length; j++) { + returnArray.push(returnData[i][j]); + } + } + return returnArray; } \ No newline at end of file diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 10c80b1db..d3963bbf0 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -2,22 +2,13 @@ import latestTime from "./helpers/latestTime"; import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { setUpPolymathNetwork, deployCappedSTOAndVerifyed, deployGPMAndVerifyed } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -98,127 +89,41 @@ contract("Issuance", accounts => { account_delegate = accounts[5]; token_owner = account_issuer; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // STEP 6: Deploy the CappedSTOFactory - - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 7: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + [I_CappedSTOFactory] = await deployCappedSTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- @@ -226,7 +131,9 @@ contract("Issuance", accounts => { }); describe("Launch SecurityToken & STO on the behalf of the issuer", async () => { + describe("Create securityToken for the issuer by the polymath", async () => { + it("POLYMATH: Should register the ticker before the generation of the security token", async () => { await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_polymath); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); @@ -236,7 +143,6 @@ contract("Issuance", accounts => { }); it("POLYMATH: Should generate the new security token with the same symbol as registered above", async () => { - console.log(name, symbol, tokenDetails, false); await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_polymath }); let _blockNo = latestBlock(); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_polymath }); From 9edfd6df34587492178f96c45f73c7296ea8dabf Mon Sep 17 00:00:00 2001 From: satyam Date: Mon, 8 Oct 2018 12:22:04 +0530 Subject: [PATCH 098/142] provide correct path to exclude the contracts --- scripts/docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docs.sh b/scripts/docs.sh index 64194ea95..db7aba417 100755 --- a/scripts/docs.sh +++ b/scripts/docs.sh @@ -36,7 +36,7 @@ create_docs() { # Command to generate the documentation using the solidity-docgen migrate=$(SOLC_ARGS="openzeppelin-solidity="$CORE_ROUTE"/node_modules/openzeppelin-solidity" \ -solidity-docgen -x $CORE_ROUTE/contracts/external,$CORE_ROUTE/contracts/mocks $CORE_ROUTE $CORE_ROUTE/contracts $CORE_ROUTE/polymath-developer-portal/) +solidity-docgen -x external/oraclizeAPI.sol,mocks/MockPolyOracle.sol,oracles/PolyOracle.sol $CORE_ROUTE $CORE_ROUTE/contracts $CORE_ROUTE/polymath-developer-portal/) echo "Successfully docs are generated..." From 627a4e368b3b77873d2a159bca91087c932d4eb0 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Mon, 8 Oct 2018 10:03:01 +0200 Subject: [PATCH 099/142] debugging test --- .../Checkpoint/WeightedVoteCheckpoint.sol | 144 +++++++++--------- .../WeightedVoteCheckpointFactory.sol | 16 +- test/weighted_vote.js | 33 ++-- 3 files changed, 105 insertions(+), 88 deletions(-) diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol index 0d88f82ca..8c125895f 100644 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol @@ -8,7 +8,7 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; * @title Checkpoint module for token weighted vote * @notice This voting system uses public votes */ -contract WeightedVoteCheckpoint is ICheckpoint { +contract WeightedVoteCheckpoint is ICheckpoint, Module { using SafeMath for uint256; struct Ballot { @@ -38,84 +38,84 @@ contract WeightedVoteCheckpoint is ICheckpoint { * @param _securityToken Address of the security token * @param _polyAddress Address of the polytoken */ - constructor(address _securityToken, address _polyAddress) public IModule(_securityToken, _polyAddress) { + constructor(address _securityToken, address _polyAddress) public Module(_securityToken, _polyAddress) { } - /** - * @notice Queries the result of a given ballot - * @param _ballotId Id of the target ballot - * @return uint256 cummulativeYes - * @return uint256 cummulativeNo - * @return uint256 totalAbstain - * @return uint256 remainingTime - */ - function getResults(uint256 _ballotId) public view returns (uint256 cummulativeYes, uint256 cummulativeNo, uint256 totalAbstain, uint256 remainingTime) { - uint256 abstain = (ballots[_ballotId].totalSupply.sub(ballots[_ballotId].cumulativeYes)).sub(ballots[_ballotId].cumulativeNo); - uint256 time = (ballots[_ballotId].endTime > now) ? ballots[_ballotId].endTime.sub(now) : 0; - return (ballots[_ballotId].cumulativeYes, ballots[_ballotId].cumulativeNo, abstain, time); - } + // /** + // * @notice Queries the result of a given ballot + // * @param _ballotId Id of the target ballot + // * @return uint256 cummulativeYes + // * @return uint256 cummulativeNo + // * @return uint256 totalAbstain + // * @return uint256 remainingTime + // */ + // function getResults(uint256 _ballotId) public view returns (uint256 cummulativeYes, uint256 cummulativeNo, uint256 totalAbstain, uint256 remainingTime) { + // uint256 abstain = (ballots[_ballotId].totalSupply.sub(ballots[_ballotId].cumulativeYes)).sub(ballots[_ballotId].cumulativeNo); + // uint256 time = (ballots[_ballotId].endTime > now) ? ballots[_ballotId].endTime.sub(now) : 0; + // return (ballots[_ballotId].cumulativeYes, ballots[_ballotId].cumulativeNo, abstain, time); + // } - /** - * @notice Allows a token holder to cast their vote on a specific ballot - * @param _vote The vote (true/false) in favor or against the proposal - * @param _ballotId The index of the target ballot - * @return bool success - */ - function castVote(bool _vote, uint256 _ballotId) public returns (bool) { - require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); - require(ballots[_ballotId].voteByAddress[msg.sender].time == 0, "Token holder has already voted."); - uint256 checkpointId = ballots[_ballotId].checkpointId; - uint256 weight = ISecurityToken(securityToken).balanceOfAt(msg.sender,checkpointId); - require(weight > 0, "Token Holder balance is zero."); - ballots[_ballotId].voteByAddress[msg.sender].time = now; - ballots[_ballotId].voteByAddress[msg.sender].weight = weight; - ballots[_ballotId].voteByAddress[msg.sender].vote = _vote; - ballots[_ballotId].numVotes = ballots[_ballotId].numVotes.add(1); - if (_vote == true) { - ballots[_ballotId].cumulativeYes = ballots[_ballotId].cumulativeYes.add(weight); - } else { - ballots[_ballotId].cumulativeNo = ballots[_ballotId].cumulativeNo.add(weight); - } - emit VoteCasted(_ballotId, now, msg.sender, weight, _vote); - return true; - } + // /** + // * @notice Allows a token holder to cast their vote on a specific ballot + // * @param _vote The vote (true/false) in favor or against the proposal + // * @param _ballotId The index of the target ballot + // * @return bool success + // */ + // function castVote(bool _vote, uint256 _ballotId) public returns (bool) { + // require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); + // require(ballots[_ballotId].voteByAddress[msg.sender].time == 0, "Token holder has already voted."); + // uint256 checkpointId = ballots[_ballotId].checkpointId; + // uint256 weight = ISecurityToken(securityToken).balanceOfAt(msg.sender,checkpointId); + // require(weight > 0, "Token Holder balance is zero."); + // ballots[_ballotId].voteByAddress[msg.sender].time = now; + // ballots[_ballotId].voteByAddress[msg.sender].weight = weight; + // ballots[_ballotId].voteByAddress[msg.sender].vote = _vote; + // ballots[_ballotId].numVotes = ballots[_ballotId].numVotes.add(1); + // if (_vote == true) { + // ballots[_ballotId].cumulativeYes = ballots[_ballotId].cumulativeYes.add(weight); + // } else { + // ballots[_ballotId].cumulativeNo = ballots[_ballotId].cumulativeNo.add(weight); + // } + // emit VoteCasted(_ballotId, now, msg.sender, weight, _vote); + // return true; + // } - /** - * @notice Allows the token issuer to create a ballot - * @param _duration The duration of the voting period in seconds - * @return bool success - */ - function createBallot(uint256 _duration) public onlyOwner returns (bool) { - uint256 ballotId = ballots.length; - uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); - uint256 currentSupply = ISecurityToken(securityToken).totalSupply(); - uint256 endTime = now.add(_duration); - ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0)); - emit BallotCreated(now, endTime, ballotId, checkpointId); - return true; - } + // /** + // * @notice Allows the token issuer to create a ballot + // * @param _duration The duration of the voting period in seconds + // * @return bool success + // */ + // function createBallot(uint256 _duration) public onlyOwner returns (bool) { + // uint256 ballotId = ballots.length; + // uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); + // uint256 currentSupply = ISecurityToken(securityToken).totalSupply(); + // uint256 endTime = now.add(_duration); + // ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0)); + // emit BallotCreated(now, endTime, ballotId, checkpointId); + // return true; + // } - /** - * @notice Allows the token issuer to create a ballot with custom settings - * @param _startTime Start time of the voting period in Unix Epoch time - * @param _endTime End time of the voting period in Unix Epoch time - * @param _checkpointId Index of the checkpoint to use for token balances - * @return bool success - */ - function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner returns (bool) { - require(_endTime >= _startTime); - uint256 ballotId = ballots.length; - uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); - ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0)); - emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); - return true; - } + // /** + // * @notice Allows the token issuer to create a ballot with custom settings + // * @param _startTime Start time of the voting period in Unix Epoch time + // * @param _endTime End time of the voting period in Unix Epoch time + // * @param _checkpointId Index of the checkpoint to use for token balances + // * @return bool success + // */ + // function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner returns (bool) { + // require(_endTime >= _startTime); + // uint256 ballotId = ballots.length; + // uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); + // ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0)); + // emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); + // return true; + // } - /** - * @notice Init function i.e generalise function to maintain the structure of the module contract - * @return bytes4 - */ + // /** + // * @notice Init function i.e generalise function to maintain the structure of the module contract + // * @return bytes4 + // */ function getInitFunction() public returns(bytes4) { return bytes4(0); } diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol index 0531826aa..090e60eeb 100644 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol @@ -1,12 +1,12 @@ pragma solidity ^0.4.24; import "./WeightedVoteCheckpoint.sol"; -import "../../interfaces/IModuleFactory.sol"; +import "../ModuleFactory.sol"; /** * @title Factory for deploying WeightedVoteCheckpoint module */ -contract WeightedVoteCheckpointFactory is IModuleFactory { +contract WeightedVoteCheckpointFactory is ModuleFactory { /** * @notice Constructor @@ -16,8 +16,14 @@ contract WeightedVoteCheckpointFactory is IModuleFactory { * @param _subscriptionCost Subscription cost of the module */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public - IModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { + version = "1.0.0"; + name = "WeightedVoteCheckpoint"; + title = "Weighted Vote Checkpoint"; + description = "Weighted votes based on token amount"; + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); } @@ -31,9 +37,9 @@ contract WeightedVoteCheckpointFactory is IModuleFactory { return address(new WeightedVoteCheckpoint(msg.sender, address(polyToken))); } - * + /** * @notice Type of the Module factory - + */ function getType() public view returns(uint8) { return 4; } diff --git a/test/weighted_vote.js b/test/weighted_vote.js index f5a0688b3..aae8a7028 100644 --- a/test/weighted_vote.js +++ b/test/weighted_vote.js @@ -72,6 +72,7 @@ contract('WeightedVoteCheckpoint', accounts => { const initRegFee = 250 * Math.pow(10, 18); before(async() => { + // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -119,15 +120,24 @@ contract('WeightedVoteCheckpoint', accounts => { "0x0000000000000000000000000000000000000000", "GeneralDelegateManagerFactory contract was not deployed" ); - + console.log("1"); // STEP 4: Deploy the WeightedVoteCheckpointFactory - I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); assert.notEqual( I_WeightedVoteCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "WeightedVoteCheckpointFactory contract was not deployed" ); + console.log("2"); + // // Step 11: update the registries addresses from the PolymathRegistry contract + // await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + // await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + // await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + // await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + // await I_MRProxied.updateFromRegistry({from: account_polymath}); + + // STEP 5: Register the Modules with the ModuleRegistry contract // (A) : Register the GeneralTransferManagerFactory @@ -185,7 +195,7 @@ contract('WeightedVoteCheckpoint', accounts => { await I_ModuleRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistry.address, {from: account_polymath}); // Printing all the contract addresses - console.log(`\nPolymath Network Smart Contracts Deployed:\n + console.log(`\nPolymathh Network Smart Contracts Deployed:\n ModuleRegistry: ${I_ModuleRegistry.address}\n GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address}\n GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address}\n @@ -196,14 +206,15 @@ contract('WeightedVoteCheckpoint', accounts => { `); }); - // describe("Generate the SecurityToken", async() => { + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); - // it("Should register the ticker before the generation of the security token", async () => { - // await I_PolyToken.approve(I_TickerRegistry.address, initRegFee, { from: token_owner }); - // let tx = await I_TickerRegistry.registerTicker(token_owner, symbol, contact, swarmHash, { from : token_owner }); - // assert.equal(tx.logs[0].args._owner, token_owner); - // assert.equal(tx.logs[0].args._symbol, symbol.toUpperCase()); - // }); // it("Should generate the new security token with the same symbol as registered above", async () => { // await I_PolyToken.approve(I_SecurityTokenRegistry.address, initRegFee, { from: token_owner }); @@ -446,5 +457,5 @@ contract('WeightedVoteCheckpoint', accounts => { // assert.equal(tx[1], web3.utils.toWei('1', 'ether'), "Failed to get results"); // assert.equal(tx[2], 0, "Failed to get results"); // }); - // }); + }); }); From 865af7abfe71c9f7cc7aeea23083159c273a09e4 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Mon, 8 Oct 2018 11:02:34 +0200 Subject: [PATCH 100/142] new test file from scratch --- test/weighted_vote_oct.js | 342 ++++++++++++++++++ ...{weighted_vote.js => weighted_vote_old.js} | 0 2 files changed, 342 insertions(+) create mode 100644 test/weighted_vote_oct.js rename test/{weighted_vote.js => weighted_vote_old.js} (100%) diff --git a/test/weighted_vote_oct.js b/test/weighted_vote_oct.js new file mode 100644 index 000000000..f8de9cdc0 --- /dev/null +++ b/test/weighted_vote_oct.js @@ -0,0 +1,342 @@ +import latestTime from './helpers/latestTime'; +import {signData} from './helpers/signData'; +import { pk } from './helpers/testprivateKey'; +import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; +import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; +import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; + +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); +const DummySTO = artifacts.require('./DummySTO.sol'); +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +const SecurityToken = artifacts.require('./SecurityToken.sol'); +const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); +const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); +const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); +const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); + +const WeightedVoteCheckpointFactory = artifacts.require('./WeightedVoteCheckpointFactory.sol'); +const WeightedVoteCheckpoint = artifacts.require('./WeightedVoteCheckpoint'); + +const Web3 = require('web3'); +const BigNumber = require('bignumber.js'); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract('GeneralPermissionManager', accounts => { + + // Accounts Variable declaration + let account_polymath; + let account_issuer; + let token_owner; + let token_owner_pk; + let account_investor1; + let account_investor2; + let account_investor3; + let account_investor4; + let account_delegate; + // investor Details + let fromTime = latestTime(); + let toTime = latestTime(); + let expiryTime = toTime + duration.days(15); + + let message = "Transaction Should Fail!"; + + // Contract Instance Declaration + let I_GeneralPermissionManagerFactory; + let P_GeneralPermissionManagerFactory; + let I_SecurityTokenRegistryProxy; + let P_GeneralPermissionManager; + let I_GeneralTransferManagerFactory; + let I_GeneralPermissionManager; + let I_GeneralTransferManager; + let I_ModuleRegistryProxy; + let I_ModuleRegistry; + let I_FeatureRegistry; + let I_SecurityTokenRegistry; + let I_DummySTOFactory; + let I_STFactory; + let I_SecurityToken; + let I_MRProxied; + let I_STRProxied; + let I_DummySTO; + let I_PolyToken; + let I_PolymathRegistry; + + // SecurityToken Details + const name = "Team"; + const symbol = "sap"; + const tokenDetails = "This is equity type of issuance"; + const decimals = 18; + const contact = "team@polymath.network"; + const delegateDetails = "Hello I am legit delegate"; + + // Module key + const delegateManagerKey = 1; + const transferManagerKey = 2; + const stoKey = 3; + + // Initial fee for ticker registry and security token registry + const initRegFee = web3.utils.toWei("250"); + + // Dummy STO details + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei('10', 'ether'); + const someString = "A string which is not used"; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; + + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); + + before(async() => { + // Accounts setup + account_polymath = accounts[0]; + account_issuer = accounts[1]; + + token_owner = account_issuer; + token_owner_pk = pk.account_1; + + account_investor1 = accounts[8]; + account_investor2 = accounts[9]; + account_delegate = accounts[7]; + + + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); + + // STEP 5: Deploy the GeneralDelegateManagerFactory + + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralDelegateManagerFactory contract was not deployed" + ); + + console.log("1"); + // STEP 6: Deploy the WeightedVoteCheckpointFactory + I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + assert.notEqual( + I_WeightedVoteCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "WeightedVoteCheckpointFactory contract was not deployed" + ); + console.log("2"); + + // STEP 6: Deploy the GeneralDelegateManagerFactory + + // P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + + // assert.notEqual( + // P_GeneralPermissionManagerFactory.address.valueOf(), + // "0x0000000000000000000000000000000000000000", + // "GeneralDelegateManagerFactory contract was not deployed" + // ); + + // STEP 7: Deploy the DummySTOFactory + + I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_DummySTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "DummySTOFactory contract was not deployed" + ); + + + // Step 8: Deploy the STFactory contract + + I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); + + assert.notEqual( + I_STFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "STFactory contract was not deployed", + ); + + // Step 9: Deploy the SecurityTokenRegistry contract + + I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); + + assert.notEqual( + I_SecurityTokenRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "SecurityTokenRegistry contract was not deployed", + ); + + // Step 10: Deploy the proxy and attach the implementation contract to it. + I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); + let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); + await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); + I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); + await I_MRProxied.updateFromRegistry({from: account_polymath}); + + // STEP 8: Register the Modules with the ModuleRegistry contract + + // (A) : Register the GeneralTransferManagerFactory + await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the GeneralDelegateManagerFactory + await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (B) : Register the Paid GeneralDelegateManagerFactory + // await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); + // await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + + // (C) : Register the STOFactory + await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + + // Printing all the contract addresses + console.log(` + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistryProxy ${ModuleRegistryProxy.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + DummySTOFactory: ${I_DummySTOFactory.address} + ----------------------------------------------------------------------------- + `); + }); + + describe("Generate the SecurityToken", async() => { + + it("Should register the ticker before the generation of the security token", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); + }); + + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let _blockNo = latestBlock(); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._types[0].toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + }); + + // it("Should successfully attach the General permission manager factory with the security token", async () => { + // let errorThrown = false; + // await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + // try { + // const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + // } catch(error) { + // console.log(` tx -> failed because Token is not paid`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // }); + + // it("Should successfully attach the General permission manager factory with the security token", async () => { + // let snapId = await takeSnapshot(); + // await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + // const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + // assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + // assert.equal( + // web3.utils.toAscii(tx.logs[3].args._name) + // .replace(/\u0000/g, ''), + // "GeneralPermissionManager", + // "GeneralPermissionManagerFactory module was not added" + // ); + // P_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[3].args._module); + // await revertToSnapshot(snapId); + // }); + + it("Should successfully attach the General permission manager factory with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), + "GeneralPermissionManager", + "GeneralPermissionManagerFactory module was not added" + ); + I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); + }); + }); + + describe("General Permission Manager test cases", async() => { + + }); + + describe("General Permission Manager Factory test cases", async() => { + + }); + +}); diff --git a/test/weighted_vote.js b/test/weighted_vote_old.js similarity index 100% rename from test/weighted_vote.js rename to test/weighted_vote_old.js From e7c04b20d671a138685f5d0e2283113b9ac7e939 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Mon, 8 Oct 2018 11:11:16 +0200 Subject: [PATCH 101/142] factory debug --- test/weighted_vote_oct.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/weighted_vote_oct.js b/test/weighted_vote_oct.js index f8de9cdc0..879e363d5 100644 --- a/test/weighted_vote_oct.js +++ b/test/weighted_vote_oct.js @@ -28,7 +28,7 @@ const Web3 = require('web3'); const BigNumber = require('bignumber.js'); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port -contract('GeneralPermissionManager', accounts => { +contract('WeightedVoteCheckpoint', accounts => { // Accounts Variable declaration let account_polymath; From 44d28e7300f083212f03538022236f56aacdac8e Mon Sep 17 00:00:00 2001 From: satyam Date: Mon, 8 Oct 2018 14:51:06 +0530 Subject: [PATCH 102/142] remove the unnecessary calling of modules --- test/helpers/createInstances.js | 61 ++++++- test/i_Issuance.js | 4 +- test/j_manual_approval_transfer_manager.js | 195 ++++----------------- test/k_module_registry.js | 136 ++++---------- test/l_percentage_transfer_manager.js | 88 ++-------- test/m_presale_sto.js | 154 +++------------- test/n_security_token_registry.js | 137 +++------------ 7 files changed, 192 insertions(+), 583 deletions(-) diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index feabbb01f..d9b0b7a58 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -10,12 +10,15 @@ const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpointFactory.sol"); const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); +const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); +const PercentageTransferManagerFactory = artifacts.require("./PercentageTransferManagerFactory.sol"); +const ManualApprovalTransferManager = artifacts.require("./ManualApprovalTransferManager"); const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); const STFactory = artifacts.require("./STFactory.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); -const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); const PolyToken = artifacts.require("./PolyToken.sol"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); @@ -24,6 +27,8 @@ const Web3 = require("web3"); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port // Contract Instance Declaration +let I_ManualApprovalTransferManagerFactory; +let I_PercentageTransferManagerFactory; let I_EtherDividendCheckpointFactory; let I_CountTransferManagerFactory; let I_ERC20DividendCheckpointFactory; @@ -31,6 +36,7 @@ let I_GeneralPermissionManagerFactory; let I_GeneralTransferManagerFactory; let I_GeneralTransferManager; let I_ModuleRegistryProxy; +let I_PreSaleSTOFactory; let I_ModuleRegistry; let I_FeatureRegistry; let I_SecurityTokenRegistry; @@ -182,6 +188,20 @@ export async function deployGPMAndVerifyed(accountPolymath, MRProxyInstance, pol return new Array(I_GeneralPermissionManagerFactory); } +export async function deployGTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_GeneralPermissionManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralPermissionManagerFactory contract was not deployed" + ); + + // (B) : Register the GeneralDelegateManagerFactory + await registerAndVerifyByMR(I_GeneralTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_GeneralTransferManagerFactory); +} + export async function deployDummySTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { I_DummySTOFactory = await DummySTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); @@ -235,7 +255,6 @@ export async function deployCountTMAndVerifyed(accountPolymath, MRProxyInstance, export async function deployCappedSTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { I_CappedSTOFactory = await CappedSTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); - assert.notEqual( I_CappedSTOFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", @@ -247,6 +266,44 @@ export async function deployCappedSTOAndVerifyed(accountPolymath, MRProxyInstanc } +export async function deployManualApprovalTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + assert.notEqual( + I_ManualApprovalTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ManualApprovalTransferManagerFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_ManualApprovalTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_ManualApprovalTransferManagerFactory); +} + +export async function deployPercentageTMAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + assert.notEqual( + I_PercentageTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "PercentageTransferManagerFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_PercentageTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_PercentageTransferManagerFactory); +} + +export async function deployPresaleSTOAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_PreSaleSTOFactory = await PreSaleSTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_PreSaleSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "PreSaleSTOFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_PreSaleSTOFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_PreSaleSTOFactory); +} + + /// Helper function function mergeReturn(returnData) { let returnArray = new Array(); diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 6aa44854f..2087e2bbe 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -106,9 +106,9 @@ contract("Issuance", accounts => { I_STRProxied ] = instances; - // STEP 5: Deploy the GeneralDelegateManagerFactory + // STEP 2: Deploy the GeneralDelegateManagerFactory [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); - // STEP 6: Deploy the CappedSTOFactory + // STEP 3: Deploy the CappedSTOFactory [I_CappedSTOFactory] = await deployCappedSTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 5276d1468..61472e4ff 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -3,24 +3,13 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployManualApprovalTMAndVerifyed, deployGPMAndVerifyed, deployCountTMAndVerifyed } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); const ManualApprovalTransferManager = artifacts.require("./ManualApprovalTransferManager"); -const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); const CountTransferManager = artifacts.require("./CountTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -83,8 +72,6 @@ contract("ManualApprovalTransferManager", accounts => { const initRegFee = web3.utils.toWei("250"); const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; before(async () => { // Accounts setup @@ -99,156 +86,44 @@ contract("ManualApprovalTransferManager", accounts => { account_investor4 = accounts[9]; account_investor5 = accounts[5]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactoryFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 6: Deploy the ManualApprovalTransferManagerFactory - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - assert.notEqual( - I_ManualApprovalTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ManualApprovalTransferManagerFactory contract was not deployed" - ); - - // STEP 7: Deploy the Paid ManualApprovalTransferManagerFactory - P_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new( - I_PolyToken.address, - web3.utils.toWei("500", "ether"), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_ManualApprovalTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ManualApprovalTransferManagerFactory contract was not deployed" - ); - - // STEP 8: Deploy the CountTransferManagerFactory - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_CountTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CountTransferManagerFactory contract was not deployed" - ); - - // Step 10: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 11: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 12: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 13: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 9: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the ManualApprovalTransferManagerFactory - await I_MRProxied.registerModule(I_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the ManualApprovalTransferManagerFactory - await I_MRProxied.registerModule(P_ManualApprovalTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_ManualApprovalTransferManagerFactory.address, true, { from: account_polymath }); - - // (D) : Register the CountTransferManagerFactory - await I_MRProxied.registerModule(I_CountTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, true, { from: account_polymath }); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 2: Deploy the GeneralDelegateManagerFactory + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + // STEP 3: Deploy the ManualApprovalTransferManagerFactory + [I_ManualApprovalTransferManagerFactory] = await deployManualApprovalTMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + // STEP 4: Deploy the Paid ManualApprovalTransferManagerFactory + [P_ManualApprovalTransferManagerFactory] = await deployManualApprovalTMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); + // STEP 5: Deploy the CountTransferManagerFactory + [I_CountTransferManagerFactory] = await deployCountTMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} ManualApprovalTransferManagerFactory: ${I_ManualApprovalTransferManagerFactory.address} CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} diff --git a/test/k_module_registry.js b/test/k_module_registry.js index 76cc9faea..00da52285 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -1,25 +1,15 @@ import latestTime from "./helpers/latestTime"; -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { duration, ensureException, latestBlock } from "./helpers/utils"; import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); -const CappedSTO = artifacts.require("./CappedSTO.sol"); const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); -const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const MockFactory = artifacts.require("./MockFactory.sol"); const TestSTOFactory = artifacts.require("./TestSTOFactory.sol"); @@ -95,7 +85,6 @@ contract("ModuleRegistry", accounts => { const rate = 1000; const fundRaiseType = [0]; const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; const MRProxyParameters = ["address", "address"]; before(async () => { @@ -109,100 +98,37 @@ contract("ModuleRegistry", accounts => { account_temp = accounts[8]; token_owner = account_issuer; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_ModuleRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ModuleRegistry contract was not deployed" - ); - - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - let tx = await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - assert.notEqual( - I_FeatureRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "FeatureRegistry contract was not deployed" - ); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); }); @@ -265,8 +191,8 @@ contract("ModuleRegistry", accounts => { assert.equal(tx.logs[0].args._owner, account_polymath, "Should be the right owner"); let _list = await I_MRProxied.getModulesByType(transferManagerKey); - assert.equal(_list.length, 1, "Length should be 1"); - assert.equal(_list[0], I_GeneralTransferManagerFactory.address); + assert.equal(_list.length, 2, "Length should be 2"); + assert.equal(_list[1], I_GeneralTransferManagerFactory.address); let _reputation = await I_MRProxied.getReputationByFactory(I_GeneralTransferManagerFactory.address); assert.equal(_reputation.length, 0); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index c9c9173ee..c9e03ecfb 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -1,12 +1,10 @@ import latestTime from "./helpers/latestTime"; -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; -import { setUpPolymathNetwork } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployPercentageTMAndVerified } from "./helpers/createInstances"; import { catchRevert } from "./helpers/exceptions"; -const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const PercentageTransferManagerFactory = artifacts.require("./PercentageTransferManagerFactory.sol"); const PercentageTransferManager = artifacts.require("./PercentageTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); const SecurityToken = artifacts.require("./SecurityToken.sol"); @@ -84,9 +82,6 @@ contract("PercentageTransferManager", accounts => { ] }, [holderPercentage, false]); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - before(async() => { // Accounts setup account_polymath = accounts[0]; @@ -114,54 +109,15 @@ contract("PercentageTransferManager", accounts => { I_STRProxied ] = instances; - // STEP 4(b): Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); + // STEP 2: Deploy the GeneralDelegateManagerFactory + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 4(c): Deploy the PercentageTransferManager - I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - assert.notEqual( - I_PercentageTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PercentageTransferManagerFactory contract was not deployed" - ); - - // STEP 4(d): Deploy the PercentageTransferManager - P_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new( - I_PolyToken.address, - web3.utils.toWei("500", "ether"), - 0, - 0, - { from: account_polymath } - ); - assert.notEqual( - P_PercentageTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PercentageTransferManagerFactory contract was not deployed" - ); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the PercentageTransferManagerFactory - await I_MRProxied.registerModule(I_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PercentageTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid PercentageTransferManagerFactory - await I_MRProxied.registerModule(P_PercentageTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_PercentageTransferManagerFactory.address, true, { from: account_polymath }); + // STEP 3(a): Deploy the PercentageTransferManager + [I_PercentageTransferManagerFactory] = await deployPercentageTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); + // STEP 4(b): Deploy the PercentageTransferManager + [P_PercentageTransferManagerFactory] = await deployPercentageTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); + // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- @@ -355,21 +311,9 @@ contract("PercentageTransferManager", accounts => { it("Should not be able to transfer between existing token holders over limit", async () => { await catchRevert(I_SecurityToken.transfer(account_investor3, web3.utils.toWei("2", "ether"), { from: account_investor1 })); }); - - it("Should unpause the tranfers at transferManager level", async() => { - await I_PercentageTransferManager.unpause({from: token_owner}); - }) it("Should not be able to mint token amount over limit", async() => { - let errorThrown = false; - try { - await I_SecurityToken.mint(account_investor3, web3.utils.toWei('100', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> Too high minting`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert(I_SecurityToken.mint(account_investor3, web3.utils.toWei('100', 'ether'), { from: token_owner })) }); it("Allow unlimited primary issuance and remint", async() => { @@ -380,15 +324,9 @@ contract("PercentageTransferManager", accounts => { }); it("Should not be able to transfer between existing token holders over limit", async() => { - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> Too many holders`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor3, web3.utils.toWei('2', 'ether'), { from: account_investor1 }) + ) }); it("Modify holder percentage to 100", async () => { diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index a59d6c553..df605d86e 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -3,22 +3,12 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployPresaleSTOAndVerified } from "./helpers/createInstances" -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); const PreSaleSTO = artifacts.require("./PreSaleSTO.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -42,7 +32,6 @@ contract("PreSaleSTO", accounts => { let expiryTime; // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; let I_SecurityTokenRegistryProxy; let I_GeneralTransferManagerFactory; let I_GeneralPermissionManager; @@ -81,8 +70,6 @@ contract("PreSaleSTO", accounts => { const initRegFee = web3.utils.toWei("250"); let endTime; const STOParameters = ["uint256"]; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; before(async () => { // Accounts setup @@ -94,130 +81,39 @@ contract("PreSaleSTO", accounts => { account_fundsReceiver = accounts[2]; token_owner = account_issuer; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 4: Deploy the PreSaleSTOFactory - - I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: token_owner }); - - assert.notEqual( - I_PreSaleSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PreSaleSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); + [I_PreSaleSTOFactory] = await deployPresaleSTOAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.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 27970c102..6bf13022c 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -3,24 +3,15 @@ import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployDummySTOAndVerifyed } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const DummySTO = artifacts.require("./DummySTO.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.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"); -const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyToken = artifacts.require("./PolyToken.sol"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); + const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -47,7 +38,6 @@ contract("SecurityTokenRegistry", accounts => { const message = "Transaction Should Fail!!"; // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; let I_GeneralTransferManagerFactory; let I_GeneralPermissionManager; let I_GeneralTransferManager; @@ -111,68 +101,25 @@ contract("SecurityTokenRegistry", accounts => { token_owner = account_issuer; dummy_token = accounts[3]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // Step 6: Deploy the STversionProxy contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 8: Deploy the CappedSTOFactory - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 1000 * Math.pow(10, 18), 0, 0, { from: token_owner }); - - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "TestSTOFactory contract was not deployed" - ); - + [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Step 9: Deploy the SecurityTokenRegistry I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); @@ -185,51 +132,21 @@ contract("SecurityTokenRegistry", accounts => { // Step 9 (a): Deploy the proxy I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - - // Step 10: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.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_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // STEP 4: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- From df02a685cce37893ccf33b1952104475164bb655 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Mon, 8 Oct 2018 14:53:32 +0200 Subject: [PATCH 103/142] rebased branch on dev 1.5.0 and rewrite a new test --- .../Checkpoint/WeightedVoteCheckpoint.sol | 132 ++--- .../WeightedVoteCheckpointFactory.sol | 38 +- test/weighted_vote_oct.js | 274 +++++++--- test/weighted_vote_old.js | 482 +++++++++--------- 4 files changed, 536 insertions(+), 390 deletions(-) diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol index 8c125895f..39de9e7bc 100644 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol @@ -42,75 +42,75 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { } - // /** - // * @notice Queries the result of a given ballot - // * @param _ballotId Id of the target ballot - // * @return uint256 cummulativeYes - // * @return uint256 cummulativeNo - // * @return uint256 totalAbstain - // * @return uint256 remainingTime - // */ - // function getResults(uint256 _ballotId) public view returns (uint256 cummulativeYes, uint256 cummulativeNo, uint256 totalAbstain, uint256 remainingTime) { - // uint256 abstain = (ballots[_ballotId].totalSupply.sub(ballots[_ballotId].cumulativeYes)).sub(ballots[_ballotId].cumulativeNo); - // uint256 time = (ballots[_ballotId].endTime > now) ? ballots[_ballotId].endTime.sub(now) : 0; - // return (ballots[_ballotId].cumulativeYes, ballots[_ballotId].cumulativeNo, abstain, time); - // } + /** + * @notice Queries the result of a given ballot + * @param _ballotId Id of the target ballot + * @return uint256 cummulativeYes + * @return uint256 cummulativeNo + * @return uint256 totalAbstain + * @return uint256 remainingTime + */ + function getResults(uint256 _ballotId) public view returns (uint256 cummulativeYes, uint256 cummulativeNo, uint256 totalAbstain, uint256 remainingTime) { + uint256 abstain = (ballots[_ballotId].totalSupply.sub(ballots[_ballotId].cumulativeYes)).sub(ballots[_ballotId].cumulativeNo); + uint256 time = (ballots[_ballotId].endTime > now) ? ballots[_ballotId].endTime.sub(now) : 0; + return (ballots[_ballotId].cumulativeYes, ballots[_ballotId].cumulativeNo, abstain, time); + } - // /** - // * @notice Allows a token holder to cast their vote on a specific ballot - // * @param _vote The vote (true/false) in favor or against the proposal - // * @param _ballotId The index of the target ballot - // * @return bool success - // */ - // function castVote(bool _vote, uint256 _ballotId) public returns (bool) { - // require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); - // require(ballots[_ballotId].voteByAddress[msg.sender].time == 0, "Token holder has already voted."); - // uint256 checkpointId = ballots[_ballotId].checkpointId; - // uint256 weight = ISecurityToken(securityToken).balanceOfAt(msg.sender,checkpointId); - // require(weight > 0, "Token Holder balance is zero."); - // ballots[_ballotId].voteByAddress[msg.sender].time = now; - // ballots[_ballotId].voteByAddress[msg.sender].weight = weight; - // ballots[_ballotId].voteByAddress[msg.sender].vote = _vote; - // ballots[_ballotId].numVotes = ballots[_ballotId].numVotes.add(1); - // if (_vote == true) { - // ballots[_ballotId].cumulativeYes = ballots[_ballotId].cumulativeYes.add(weight); - // } else { - // ballots[_ballotId].cumulativeNo = ballots[_ballotId].cumulativeNo.add(weight); - // } - // emit VoteCasted(_ballotId, now, msg.sender, weight, _vote); - // return true; - // } + /** + * @notice Allows a token holder to cast their vote on a specific ballot + * @param _vote The vote (true/false) in favor or against the proposal + * @param _ballotId The index of the target ballot + * @return bool success + */ + function castVote(bool _vote, uint256 _ballotId) public returns (bool) { + require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); + require(ballots[_ballotId].voteByAddress[msg.sender].time == 0, "Token holder has already voted."); + uint256 checkpointId = ballots[_ballotId].checkpointId; + uint256 weight = ISecurityToken(securityToken).balanceOfAt(msg.sender,checkpointId); + require(weight > 0, "Token Holder balance is zero."); + ballots[_ballotId].voteByAddress[msg.sender].time = now; + ballots[_ballotId].voteByAddress[msg.sender].weight = weight; + ballots[_ballotId].voteByAddress[msg.sender].vote = _vote; + ballots[_ballotId].numVotes = ballots[_ballotId].numVotes.add(1); + if (_vote == true) { + ballots[_ballotId].cumulativeYes = ballots[_ballotId].cumulativeYes.add(weight); + } else { + ballots[_ballotId].cumulativeNo = ballots[_ballotId].cumulativeNo.add(weight); + } + emit VoteCasted(_ballotId, now, msg.sender, weight, _vote); + return true; + } - // /** - // * @notice Allows the token issuer to create a ballot - // * @param _duration The duration of the voting period in seconds - // * @return bool success - // */ - // function createBallot(uint256 _duration) public onlyOwner returns (bool) { - // uint256 ballotId = ballots.length; - // uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); - // uint256 currentSupply = ISecurityToken(securityToken).totalSupply(); - // uint256 endTime = now.add(_duration); - // ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0)); - // emit BallotCreated(now, endTime, ballotId, checkpointId); - // return true; - // } + /** + * @notice Allows the token issuer to create a ballot + * @param _duration The duration of the voting period in seconds + * @return bool success + */ + function createBallot(uint256 _duration) public onlyOwner returns (bool) { + uint256 ballotId = ballots.length; + uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); + uint256 currentSupply = ISecurityToken(securityToken).totalSupply(); + uint256 endTime = now.add(_duration); + ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0)); + emit BallotCreated(now, endTime, ballotId, checkpointId); + return true; + } - // /** - // * @notice Allows the token issuer to create a ballot with custom settings - // * @param _startTime Start time of the voting period in Unix Epoch time - // * @param _endTime End time of the voting period in Unix Epoch time - // * @param _checkpointId Index of the checkpoint to use for token balances - // * @return bool success - // */ - // function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner returns (bool) { - // require(_endTime >= _startTime); - // uint256 ballotId = ballots.length; - // uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); - // ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0)); - // emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); - // return true; - // } + /** + * @notice Allows the token issuer to create a ballot with custom settings + * @param _startTime Start time of the voting period in Unix Epoch time + * @param _endTime End time of the voting period in Unix Epoch time + * @param _checkpointId Index of the checkpoint to use for token balances + * @return bool success + */ + function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner returns (bool) { + require(_endTime >= _startTime); + uint256 ballotId = ballots.length; + uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); + ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0)); + emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); + return true; + } // /** // * @notice Init function i.e generalise function to maintain the structure of the module contract diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol index 090e60eeb..6fcf9b2d9 100644 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol @@ -37,45 +37,61 @@ contract WeightedVoteCheckpointFactory is ModuleFactory { return address(new WeightedVoteCheckpoint(msg.sender, address(polyToken))); } - /** + /** * @notice Type of the Module factory */ - function getType() public view returns(uint8) { - return 4; + function getTypes() external view returns(uint8[]) { + uint8[] memory res = new uint8[](1); + res[0] = 4; + return res; } /** * @notice Get the name of the Module */ function getName() public view returns(bytes32) { - return "WeightedVoteCheckpoint"; + return name; } /** * @notice Get the description of the Module */ - function getDescription() public view returns(string) { - return "Create votes for single issue token weighted votes"; + function getDescription() external view returns(string) { + return description; } /** * @notice Get the title of the Module */ - function getTitle() public view returns(string) { - return "Weighted Vote Checkpoint"; + function getTitle() external view returns(string) { + return title; + } + + /** + * @notice Get the version of the Module + */ + function getVersion() external view returns(string) { + return version; + } + + /** + * @notice Get the setup cost of the module + */ + function getSetupCost() external view returns (uint256) { + return setupCost; } /** * @notice Get the Instructions that helped to used the module */ - function getInstructions() public view returns(string) { - return "Create a vote which allows token holders to vote on an issue with a weight proportional to their balances at the point the vote is created"; + function getInstructions() external view returns(string) { + return "Create a vote which allows token holders to vote on an issue with a weight proportional to their balances at the point the vote is created."; } /** * @notice Get the tags related to the module factory */ - function getTags() public view returns(bytes32[]) { + function getTags() external view returns(bytes32[]) { bytes32[] memory availableTags = new bytes32[](0); return availableTags; } diff --git a/test/weighted_vote_oct.js b/test/weighted_vote_oct.js index 879e363d5..9d88ce873 100644 --- a/test/weighted_vote_oct.js +++ b/test/weighted_vote_oct.js @@ -39,7 +39,7 @@ contract('WeightedVoteCheckpoint', accounts => { let account_investor2; let account_investor3; let account_investor4; - let account_delegate; + let account_temp; // investor Details let fromTime = latestTime(); let toTime = latestTime(); @@ -48,10 +48,7 @@ contract('WeightedVoteCheckpoint', accounts => { let message = "Transaction Should Fail!"; // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let P_GeneralPermissionManagerFactory; let I_SecurityTokenRegistryProxy; - let P_GeneralPermissionManager; let I_GeneralTransferManagerFactory; let I_GeneralPermissionManager; let I_GeneralTransferManager; @@ -67,6 +64,8 @@ contract('WeightedVoteCheckpoint', accounts => { let I_DummySTO; let I_PolyToken; let I_PolymathRegistry; + let I_WeightedVoteCheckpointFactory; + let I_WeightedVoteCheckpoint; // SecurityToken Details const name = "Team"; @@ -80,6 +79,7 @@ contract('WeightedVoteCheckpoint', accounts => { const delegateManagerKey = 1; const transferManagerKey = 2; const stoKey = 3; + const checkpointKey = 4; // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); @@ -103,9 +103,11 @@ contract('WeightedVoteCheckpoint', accounts => { token_owner = account_issuer; token_owner_pk = pk.account_1; - account_investor1 = accounts[8]; - account_investor2 = accounts[9]; - account_delegate = accounts[7]; + account_investor1 = accounts[6]; + account_investor2 = accounts[7]; + account_investor3 = accounts[8]; + account_investor4 = accounts[9]; + account_temp = accounts[2]; // ----------- POLYMATH NETWORK Configuration ------------ @@ -144,35 +146,17 @@ contract('WeightedVoteCheckpoint', accounts => { "GeneralTransferManagerFactory contract was not deployed" ); - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + // STEP 5: Deploy the WeightedVoteCheckpointFactory console.log("1"); - // STEP 6: Deploy the WeightedVoteCheckpointFactory + I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); assert.notEqual( I_WeightedVoteCheckpointFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "WeightedVoteCheckpointFactory contract was not deployed" ); - console.log("2"); - - // STEP 6: Deploy the GeneralDelegateManagerFactory - - // P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); - - // assert.notEqual( - // P_GeneralPermissionManagerFactory.address.valueOf(), - // "0x0000000000000000000000000000000000000000", - // "GeneralDelegateManagerFactory contract was not deployed" - // ); + console.log("deployed weight vote factory to "+I_WeightedVoteCheckpointFactory.address); // STEP 7: Deploy the DummySTOFactory @@ -225,8 +209,8 @@ contract('WeightedVoteCheckpoint', accounts => { await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + await I_MRProxied.registerModule(I_WeightedVoteCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(I_WeightedVoteCheckpointFactory.address, true, { from: account_polymath }); // (B) : Register the Paid GeneralDelegateManagerFactory // await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); @@ -290,53 +274,199 @@ contract('WeightedVoteCheckpoint', accounts => { I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - // it("Should successfully attach the General permission manager factory with the security token", async () => { - // let errorThrown = false; - // await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - // try { - // const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - // } catch(error) { - // console.log(` tx -> failed because Token is not paid`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should successfully attach the General permission manager factory with the security token", async () => { - // let snapId = await takeSnapshot(); - // await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - // const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - // assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); - // assert.equal( - // web3.utils.toAscii(tx.logs[3].args._name) - // .replace(/\u0000/g, ''), - // "GeneralPermissionManager", - // "GeneralPermissionManagerFactory module was not added" - // ); - // P_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[3].args._module); - // await revertToSnapshot(snapId); - // }); - - it("Should successfully attach the General permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "GeneralPermissionManager", - "GeneralPermissionManagerFactory module was not added" - ); - I_GeneralPermissionManager = GeneralPermissionManager.at(tx.logs[2].args._module); + + it("Should successfully attach the Weighted Vote Checkpoint factory with the security token", async () => { + const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "0x", 0, 0, { from: token_owner }); + console.log("weightVoteFactory Address is " + I_WeightedVoteCheckpointFactory.address); + console.log(tx.logs[2].args); + assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); + assert.equal(web3.utils.hexToUtf8(tx.logs[2].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); + I_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[2].args._module); + }); + }); + + describe("Preparation", async() => { + it("Should successfully mint tokens for first investor account", async() => { + await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + }); + + it("Should successfully mint tokens for second investor account", async() => { + await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + }); + }); + + describe("Create ballot", async() => { + + it("Should fail to create a new ballot if not owner", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: account_temp }); + } catch(error) { + console.log(` tx -> failed because msg.sender is not owner`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully create a new ballot", async() => { + let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: token_owner }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); + }); + }); + + describe("Create custom ballot", async() => { + + it("Should fail to create a new custom ballot with endTime before startTime", async() => { + let errorThrown = false; + try { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(5); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because endTime before startTime`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to create a new custom ballot if checkpointId does not exist", async() => { + let errorThrown = false; + try { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(15); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 10, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because checkpointId does not exist`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to create a new custom ballot if not owner", async() => { + let errorThrown = false; + try { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(15); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: account_temp }); + } catch(error) { + console.log(` tx -> failed because msg.sender is not owner`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully create a new custom ballot", async() => { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(15); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); }); }); - describe("General Permission Manager test cases", async() => { - + describe("Cast vote", async() => { + + it("Should fail to cast a vote if token balance is zero", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor3 }); + } catch(error) { + console.log(` tx -> failed because token balance is zero`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to cast a vote if voting period has not started", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); + } catch(error) { + console.log(` tx -> failed because voting period has not started`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to cast a vote if voting period has ended", async() => { + await increaseTime(duration.minutes(20)); + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); + } catch(error) { + console.log(` tx -> failed because voting period has ended`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully cast a vote from first investor", async() => { + let tx = await I_WeightedVoteCheckpoint.castVote(false, 0, { from: account_investor1 }); + + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed to record vote"); + assert.equal(tx.logs[0].args._vote, false, "Failed to record vote"); + assert.equal(tx.logs[0].args._weight, web3.utils.toWei('1', 'ether'), "Failed to record vote"); + assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); + assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); + }); + + it("Should successfully cast a vote from second investor", async() => { + let tx = await I_WeightedVoteCheckpoint.castVote(true, 0, { from: account_investor2 }); + + assert.equal(tx.logs[0].args._investor, account_investor2, "Failed to record vote"); + assert.equal(tx.logs[0].args._vote, true, "Failed to record vote"); + assert.equal(tx.logs[0].args._weight, web3.utils.toWei('2', 'ether'), "Failed to record vote"); + assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); + assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); + }); + + it("Should fail to cast a vote again", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(false,0, { from: account_investor1 }); + } catch(error) { + console.log(` tx -> failed because holder already voted`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); }); - describe("General Permission Manager Factory test cases", async() => { - + describe("Get results", async() => { + + it("Should successfully get the results", async() => { + let tx = await I_WeightedVoteCheckpoint.getResults(0, { from: token_owner }); + assert.equal(tx[0], web3.utils.toWei('2', 'ether'), "Failed to get results"); + assert.equal(tx[1], web3.utils.toWei('1', 'ether'), "Failed to get results"); + assert.equal(tx[2], 0, "Failed to get results"); + }); }); }); diff --git a/test/weighted_vote_old.js b/test/weighted_vote_old.js index aae8a7028..14e3b2a18 100644 --- a/test/weighted_vote_old.js +++ b/test/weighted_vote_old.js @@ -216,246 +216,246 @@ contract('WeightedVoteCheckpoint', accounts => { }); - // it("Should generate the new security token with the same symbol as registered above", async () => { - // await I_PolyToken.approve(I_SecurityTokenRegistry.address, initRegFee, { from: token_owner }); - // let tx = await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); - - // // Verify the successful generation of the security token - // assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - // I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - // const LogAddModule = await I_SecurityToken.allEvents(); - // const log = await new Promise(function(resolve, reject) { - // LogAddModule.watch(function(error, log){ resolve(log);}); - // }); - - // // Verify that GeneralTransferManager module get added successfully or not - // assert.equal(log.args._type.toNumber(), 2); - // assert.equal( - // web3.utils.toAscii(log.args._name) - // .replace(/\u0000/g, ''), - // "GeneralTransferManager" - // ); - // LogAddModule.stopWatching(); - // }); - - // it("Should intialize the auto attached modules", async () => { - // let moduleData = await I_SecurityToken.modules(2, 0); - // I_GeneralTransferManager = GeneralTransferManager.at(moduleData[1]); - - // assert.notEqual( - // I_GeneralTransferManager.address.valueOf(), - // "0x0000000000000000000000000000000000000000", - // "GeneralTransferManager contract was not deployed", - // ); - - // }); - - // it("Should fail to attach the WeightedVoteCheckpoint module to the security token if fee not paid", async () => { - // let errorThrown = false; - // await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - // try { - // const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); - // } catch(error) { - // console.log(` tx -> failed because setup fee is not paid`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should successfully attach the WeightedVoteCheckpoint module to the security token", async () => { - // await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - // const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); - // assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); - // assert.equal(web3.utils.hexToUtf8(tx.logs[3].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); - // I_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[3].args._module); - // }); - - // }); - - // describe("Preparation", async() => { - // it("Should successfully mint tokens for first investor account", async() => { - // await I_GeneralTransferManager.modifyWhitelist( - // account_investor1, - // latestTime(), - // latestTime(), - // latestTime() + duration.days(30), - // true, - // { - // from: account_issuer, - // gas: 500000 - // }); - // await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - // }); - - // it("Should successfully mint tokens for second investor account", async() => { - // await I_GeneralTransferManager.modifyWhitelist( - // account_investor2, - // latestTime(), - // latestTime(), - // latestTime() + duration.days(30), - // true, - // { - // from: account_issuer, - // gas: 500000 - // }); - // await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - // }); - // }); - - // describe("Create ballot", async() => { - - // it("Should fail to create a new ballot if not owner", async() => { - // let errorThrown = false; - // try { - // let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: account_temp }); - // } catch(error) { - // console.log(` tx -> failed because msg.sender is not owner`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should successfully create a new ballot", async() => { - // let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: token_owner }); - // assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); - // }); - // }); - - // describe("Create custom ballot", async() => { - - // it("Should fail to create a new custom ballot with endTime before startTime", async() => { - // let errorThrown = false; - // try { - // let startTime = latestTime() + duration.minutes(10); - // let endTime = latestTime() + duration.minutes(5); - // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); - // } catch(error) { - // console.log(` tx -> failed because endTime before startTime`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should fail to create a new custom ballot if checkpointId does not exist", async() => { - // let errorThrown = false; - // try { - // let startTime = latestTime() + duration.minutes(10); - // let endTime = latestTime() + duration.minutes(15); - // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 10, { from: token_owner }); - // } catch(error) { - // console.log(` tx -> failed because checkpointId does not exist`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should fail to create a new custom ballot if not owner", async() => { - // let errorThrown = false; - // try { - // let startTime = latestTime() + duration.minutes(10); - // let endTime = latestTime() + duration.minutes(15); - // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: account_temp }); - // } catch(error) { - // console.log(` tx -> failed because msg.sender is not owner`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should successfully create a new custom ballot", async() => { - // let startTime = latestTime() + duration.minutes(10); - // let endTime = latestTime() + duration.minutes(15); - // let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); - // assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); - // }); - // }); - - // describe("Cast vote", async() => { - - // it("Should fail to cast a vote if token balance is zero", async() => { - // let errorThrown = false; - // try { - // let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor3 }); - // } catch(error) { - // console.log(` tx -> failed because token balance is zero`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should fail to cast a vote if voting period has not started", async() => { - // let errorThrown = false; - // try { - // let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); - // } catch(error) { - // console.log(` tx -> failed because voting period has not started`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should fail to cast a vote if voting period has ended", async() => { - // await increaseTime(duration.minutes(20)); - // let errorThrown = false; - // try { - // let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); - // } catch(error) { - // console.log(` tx -> failed because voting period has ended`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - - // it("Should successfully cast a vote from first investor", async() => { - // let tx = await I_WeightedVoteCheckpoint.castVote(false, 0, { from: account_investor1 }); - - // assert.equal(tx.logs[0].args._investor, account_investor1, "Failed to record vote"); - // assert.equal(tx.logs[0].args._vote, false, "Failed to record vote"); - // assert.equal(tx.logs[0].args._weight, web3.utils.toWei('1', 'ether'), "Failed to record vote"); - // assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); - // assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); - // }); - - // it("Should successfully cast a vote from second investor", async() => { - // let tx = await I_WeightedVoteCheckpoint.castVote(true, 0, { from: account_investor2 }); - - // assert.equal(tx.logs[0].args._investor, account_investor2, "Failed to record vote"); - // assert.equal(tx.logs[0].args._vote, true, "Failed to record vote"); - // assert.equal(tx.logs[0].args._weight, web3.utils.toWei('2', 'ether'), "Failed to record vote"); - // assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); - // assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); - // }); - - // it("Should fail to cast a vote again", async() => { - // let errorThrown = false; - // try { - // let tx = await I_WeightedVoteCheckpoint.castVote(false,0, { from: account_investor1 }); - // } catch(error) { - // console.log(` tx -> failed because holder already voted`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // }); - // }); - - // describe("Get results", async() => { - - // it("Should successfully get the results", async() => { - // let tx = await I_WeightedVoteCheckpoint.getResults(0, { from: token_owner }); - // assert.equal(tx[0], web3.utils.toWei('2', 'ether'), "Failed to get results"); - // assert.equal(tx[1], web3.utils.toWei('1', 'ether'), "Failed to get results"); - // assert.equal(tx[2], 0, "Failed to get results"); - // }); + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_PolyToken.approve(I_SecurityTokenRegistry.address, initRegFee, { from: token_owner }); + let tx = await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); + + // Verify the successful generation of the security token + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + + I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); + + const LogAddModule = await I_SecurityToken.allEvents(); + const log = await new Promise(function(resolve, reject) { + LogAddModule.watch(function(error, log){ resolve(log);}); + }); + + // Verify that GeneralTransferManager module get added successfully or not + assert.equal(log.args._type.toNumber(), 2); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); + LogAddModule.stopWatching(); + }); + + it("Should intialize the auto attached modules", async () => { + let moduleData = await I_SecurityToken.modules(2, 0); + I_GeneralTransferManager = GeneralTransferManager.at(moduleData[1]); + + assert.notEqual( + I_GeneralTransferManager.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManager contract was not deployed", + ); + + }); + + it("Should fail to attach the WeightedVoteCheckpoint module to the security token if fee not paid", async () => { + let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + try { + const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because setup fee is not paid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully attach the WeightedVoteCheckpoint module to the security token", async () => { + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); + assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); + assert.equal(web3.utils.hexToUtf8(tx.logs[3].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); + I_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[3].args._module); + }); + + }); + + describe("Preparation", async() => { + it("Should successfully mint tokens for first investor account", async() => { + await I_GeneralTransferManager.modifyWhitelist( + account_investor1, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + }); + + it("Should successfully mint tokens for second investor account", async() => { + await I_GeneralTransferManager.modifyWhitelist( + account_investor2, + latestTime(), + latestTime(), + latestTime() + duration.days(30), + true, + { + from: account_issuer, + gas: 500000 + }); + await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + }); + }); + + describe("Create ballot", async() => { + + it("Should fail to create a new ballot if not owner", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: account_temp }); + } catch(error) { + console.log(` tx -> failed because msg.sender is not owner`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully create a new ballot", async() => { + let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: token_owner }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); + }); + }); + + describe("Create custom ballot", async() => { + + it("Should fail to create a new custom ballot with endTime before startTime", async() => { + let errorThrown = false; + try { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(5); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because endTime before startTime`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to create a new custom ballot if checkpointId does not exist", async() => { + let errorThrown = false; + try { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(15); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 10, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because checkpointId does not exist`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to create a new custom ballot if not owner", async() => { + let errorThrown = false; + try { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(15); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: account_temp }); + } catch(error) { + console.log(` tx -> failed because msg.sender is not owner`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully create a new custom ballot", async() => { + let startTime = latestTime() + duration.minutes(10); + let endTime = latestTime() + duration.minutes(15); + let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); + }); + }); + + describe("Cast vote", async() => { + + it("Should fail to cast a vote if token balance is zero", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor3 }); + } catch(error) { + console.log(` tx -> failed because token balance is zero`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to cast a vote if voting period has not started", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); + } catch(error) { + console.log(` tx -> failed because voting period has not started`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to cast a vote if voting period has ended", async() => { + await increaseTime(duration.minutes(20)); + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); + } catch(error) { + console.log(` tx -> failed because voting period has ended`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully cast a vote from first investor", async() => { + let tx = await I_WeightedVoteCheckpoint.castVote(false, 0, { from: account_investor1 }); + + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed to record vote"); + assert.equal(tx.logs[0].args._vote, false, "Failed to record vote"); + assert.equal(tx.logs[0].args._weight, web3.utils.toWei('1', 'ether'), "Failed to record vote"); + assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); + assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); + }); + + it("Should successfully cast a vote from second investor", async() => { + let tx = await I_WeightedVoteCheckpoint.castVote(true, 0, { from: account_investor2 }); + + assert.equal(tx.logs[0].args._investor, account_investor2, "Failed to record vote"); + assert.equal(tx.logs[0].args._vote, true, "Failed to record vote"); + assert.equal(tx.logs[0].args._weight, web3.utils.toWei('2', 'ether'), "Failed to record vote"); + assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); + assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); + }); + + it("Should fail to cast a vote again", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(false,0, { from: account_investor1 }); + } catch(error) { + console.log(` tx -> failed because holder already voted`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + }); + + describe("Get results", async() => { + + it("Should successfully get the results", async() => { + let tx = await I_WeightedVoteCheckpoint.getResults(0, { from: token_owner }); + assert.equal(tx[0], web3.utils.toWei('2', 'ether'), "Failed to get results"); + assert.equal(tx[1], web3.utils.toWei('1', 'ether'), "Failed to get results"); + assert.equal(tx[2], 0, "Failed to get results"); + }); }); }); From f3a1f86f12a874a07431cb2b6cb120277b4c9fc4 Mon Sep 17 00:00:00 2001 From: satyam Date: Mon, 8 Oct 2018 18:37:33 +0530 Subject: [PATCH 104/142] remove the cruft from the securityToken.js --- test/o_security_token.js | 188 ++++++++------------------------------- 1 file changed, 39 insertions(+), 149 deletions(-) diff --git a/test/o_security_token.js b/test/o_security_token.js index 30888b60c..b5ca2dbdf 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -3,22 +3,13 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployCappedSTOAndVerifyed } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -97,8 +88,6 @@ contract("SecurityToken", accounts => { const cappedSTOSetupCost = web3.utils.toWei("20000", "ether"); const maxCost = cappedSTOSetupCost; const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; before(async () => { // Accounts setup @@ -116,122 +105,41 @@ contract("SecurityToken", accounts => { token_owner = account_issuer; account_controller = account_temp; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4 (a): Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - address_zero, - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 4 (b): Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - address_zero, - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 4 (c): Deploy the CappedSTOFactory - - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, cappedSTOSetupCost, 0, 0, { from: token_owner }); - - assert.notEqual(I_CappedSTOFactory.address.valueOf(), address_zero, "CappedSTOFactory contract was not deployed"); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); + // Step:1 Create the polymath ecosystem contract instances + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 2: Deploy the GeneralDelegateManagerFactory + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + // STEP 3: Deploy the CappedSTOFactory + [I_CappedSTOFactory] = await deployCappedSTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, cappedSTOSetupCost); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- @@ -560,43 +468,23 @@ contract("SecurityToken", accounts => { await catchRevert(I_SecurityToken.transfer(account_investor2, 10 * Math.pow(10, 18), { from: account_investor1 })); }); - it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { + it("Should fail to provide the permission to the delegate to change the transfer bools -- Bad owner", async () => { // Add permission to the deletgate (A regesteration process) await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, { from: token_owner }); let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_temp })); + await catchRevert(I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_temp })); }); it("Should provide the permission to the delegate to change the transfer bools", async () => { // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); + await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner }); + assert.isTrue(await I_GeneralPermissionManager.checkDelegate.call(account_delegate)); // Providing the permission to the delegate await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: token_owner }); - - it("Should fail to provide the permission to the delegate to change the transfer bools", async () => { - let errorThrown = false; - // Add permission to the deletgate (A regesteration process) - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "", 0, 0, {from: token_owner}); - let moduleData = (await I_SecurityToken.getModulesByType(permissionManagerKey))[0]; - I_GeneralPermissionManager = GeneralPermissionManager.at(moduleData); - try { - await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_temp }); - } catch (error) { - console.log(`${account_temp} doesn't have permissions to register the delegate`); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); - }); - - it("Should provide the permission to the delegate to change the transfer bools", async () => { - // Add permission to the deletgate (A regesteration process) - await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner}); - // Providing the permission to the delegate - await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, TM_Perm, true, { from: token_owner }); + }); it("Should activate the bool allowAllTransfer", async () => { ID_snap = await takeSnapshot(); @@ -835,6 +723,7 @@ contract("SecurityToken", accounts => { assert.equal(investors.length, 4); console.log("Total Seen Investors: " + investors.length); }); + it("Should fail to set controller status because msg.sender not owner", async () => { await catchRevert(I_SecurityToken.setController(account_controller, { from: account_controller })); }); @@ -1046,4 +935,5 @@ contract("SecurityToken", accounts => { ); }); }); -}); + +}); \ No newline at end of file From 4ee8119f99cec573e88681d61c8fa91030670929 Mon Sep 17 00:00:00 2001 From: satyam Date: Mon, 8 Oct 2018 19:04:34 +0530 Subject: [PATCH 105/142] small changes --- test/helpers/createInstances.js | 19 ++++ test/p_usd_tiered_sto.js | 162 ++++++-------------------------- 2 files changed, 48 insertions(+), 133 deletions(-) diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index d9b0b7a58..c187ce4c4 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -12,6 +12,8 @@ const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpo const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); const PercentageTransferManagerFactory = artifacts.require("./PercentageTransferManagerFactory.sol"); +const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); +const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory"); const ManualApprovalTransferManager = artifacts.require("./ManualApprovalTransferManager"); const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); const STFactory = artifacts.require("./STFactory.sol"); @@ -27,6 +29,8 @@ const Web3 = require("web3"); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port // Contract Instance Declaration +let I_USDTieredSTOProxyFactory; +let I_USDTieredSTOFactory; let I_ManualApprovalTransferManagerFactory; let I_PercentageTransferManagerFactory; let I_EtherDividendCheckpointFactory; @@ -303,6 +307,21 @@ export async function deployPresaleSTOAndVerified(accountPolymath, MRProxyInstan return new Array(I_PreSaleSTOFactory); } +export async function deployUSDTieredSTOAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({from: accountPolymath}); + + I_USDTieredSTOFactory = await USDTieredSTOFactory.new(polyToken, setupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { from: accountPolymath }); + + assert.notEqual( + I_USDTieredSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "USDTieredSTOFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_USDTieredSTOFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_USDTieredSTOFactory); +} + /// Helper function function mergeReturn(returnData) { diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 48099a17f..52f51acc2 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -3,24 +3,12 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployUSDTieredSTOAndVerified } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); -const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory"); const USDTieredSTO = artifacts.require("./USDTieredSTO.sol"); const MockOracle = artifacts.require("./MockOracle.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -88,9 +76,6 @@ contract("USDTieredSTO", accounts => { const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; - // STO Configuration Arrays let _startTime = []; let _endTime = []; @@ -217,116 +202,29 @@ contract("USDTieredSTO", accounts => { INVESTOR2 = accounts[8]; INVESTOR3 = accounts[9]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: POLYMATH - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 3: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - + // Step:1 Create the polymath ecosystem contract instances + let instances = await setUpPolymathNetwork(POLYMATH, ISSUER); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + // STEP 4: Deploy the GeneralDelegateManagerFactory + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(POLYMATH, I_MRProxied, I_PolyToken.address, 0); - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the proxy - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - - // STEP 6: Deploy the USDTieredSTOFactory - - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { - from: ISSUER - }); - - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "USDTieredSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - REGFEE, - REGFEE, - I_PolyToken.address, - POLYMATH - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); - await I_MRProxied.updateFromRegistry({ from: POLYMATH }); - - // STEP 7: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); - + // STEP 5: Deploy the USDTieredSTOFactory + [I_USDTieredSTOFactory] = await deployUSDTieredSTOAndVerified(POLYMATH, I_MRProxied, I_PolyToken.address, STOSetupCost); + // 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 @@ -336,20 +234,18 @@ contract("USDTieredSTO", accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} USDOracle: ${I_USDOracle.address} POLYOracle: ${I_POLYOracle.address} USDTieredSTOFactory: ${I_USDTieredSTOFactory.address} - USDTieredSTOProxyFactory: ${I_USDTieredSTOProxyFactory.address} ----------------------------------------------------------------------------- `); }); From d2248ff3b1da7252a527a882c94549a3c0737110 Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 9 Oct 2018 10:54:47 +0530 Subject: [PATCH 106/142] fix the tiered STO --- test/p_usd_tiered_sto.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 52f51acc2..73856e2cf 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -9,6 +9,7 @@ const USDTieredSTO = artifacts.require("./USDTieredSTO.sol"); const MockOracle = artifacts.require("./MockOracle.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -219,6 +220,7 @@ contract("USDTieredSTO", accounts => { I_STRProxied ] = instances; + I_DaiToken = await PolyTokenFaucet.new({from: POLYMATH}); // STEP 4: Deploy the GeneralDelegateManagerFactory [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(POLYMATH, I_MRProxied, I_PolyToken.address, 0); From de03d1362b5c172831a48c680c6854f38bcb774d Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 9 Oct 2018 11:39:00 +0530 Subject: [PATCH 107/142] revamp the tests --- test/r_concurrent_STO.js | 183 +++++++++------------------------------ 1 file changed, 39 insertions(+), 144 deletions(-) diff --git a/test/r_concurrent_STO.js b/test/r_concurrent_STO.js index 937378822..7912658a4 100644 --- a/test/r_concurrent_STO.js +++ b/test/r_concurrent_STO.js @@ -1,28 +1,21 @@ import latestTime from "./helpers/latestTime"; -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { + setUpPolymathNetwork, + deployDummySTOAndVerifyed, + deployCappedSTOAndVerifyed, + deployPresaleSTOAndVerified + } from "./helpers/createInstances"; + // Import contract ABIs -const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); -const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const DummySTO = artifacts.require("./DummySTO.sol"); -const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); const PreSaleSTO = artifacts.require("./PreSaleSTO.sol"); -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -38,7 +31,6 @@ contract("Concurrent STO", accounts => { let account_investor3; // Contract instance declaration - let I_GeneralPermissionManagerFactory; let I_SecurityTokenRegistryProxy; let I_GeneralPermissionManager; let I_GeneralTransferManagerFactory; @@ -74,8 +66,6 @@ contract("Concurrent STO", accounts => { // Configure function signature for STO deployment const CappedSTOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; const DummySTOParameters = ["uint256", "uint256", "uint256", "string"]; const PresaleSTOParameters = ["uint256"]; @@ -88,136 +78,41 @@ contract("Concurrent STO", accounts => { account_investor2 = accounts[4]; account_investor3 = accounts[5]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), account_issuer); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralPermissionManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the STO Factories - - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - I_PreSaleSTOFactory = await PreSaleSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: account_issuer }); - - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STO Factories - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: account_polymath }); - - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - - await I_MRProxied.registerModule(I_PreSaleSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_PreSaleSTOFactory.address, true, { from: account_polymath }); + // Step:1 Create the polymath ecosystem contract instances + let instances = await setUpPolymathNetwork(account_polymath, account_issuer); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 2: Deploy the STO Factories + + [I_CappedSTOFactory] = await deployCappedSTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, STOSetupCost); + [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, STOSetupCost); + [I_PreSaleSTOFactory] = await deployPresaleSTOAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, STOSetupCost); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} CappedSTOFactory: ${I_CappedSTOFactory.address} ----------------------------------------------------------------------------- From 1c20dbe403a12c99e501ce9dc6e2b889ac212c9f Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 9 Oct 2018 12:58:17 +0530 Subject: [PATCH 108/142] revamp the STVRM -- need to re-write the test cases --- test/x_single_trade_volume_restriction.js | 839 +++++----------------- 1 file changed, 189 insertions(+), 650 deletions(-) diff --git a/test/x_single_trade_volume_restriction.js b/test/x_single_trade_volume_restriction.js index 64813eed1..f21803e10 100644 --- a/test/x_single_trade_volume_restriction.js +++ b/test/x_single_trade_volume_restriction.js @@ -1,34 +1,16 @@ import latestTime from './helpers/latestTime'; -import { - duration, - ensureException, - promisifyLogWatch, - latestBlock -} from './helpers/utils'; -import takeSnapshot, { - increaseTime, - revertToSnapshot -} from './helpers/time'; -import { - encodeProxyCall -} from './helpers/encodeCall'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; +import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; +import { encodeModuleCall } from './helpers/encodeCall'; +import {deploySingleTradeVolumeRMAndVerified, setUpPolymathNetwork } from "./helpers/createInstances"; +import { catchRevert } from "./helpers/exceptions"; + const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const SingleTradeVolumeRestrictionManagerFactory = artifacts.require('./SingleTradeVolumeRestrictionManagerFactory.sol'); const SingleTradeVolumeRestrictionManager = artifacts.require('./SingleTradeVolumeRestrictionManager'); const CountTransferManagerFactory = artifacts.require('./CountTransferManagerFactory.sol'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -58,7 +40,6 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { // Contract Instance Declaration let I_SecurityTokenRegistryProxy - let I_GeneralPermissionManagerFactory; let I_GeneralTransferManagerFactory; let I_GeneralPermissionManager; let I_GeneralTransferManager; @@ -78,16 +59,13 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { let I_PolyToken; let I_PolymathRegistry; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - // SecurityToken Details - const swarmHash = "dagwrgwgvwergwrvwrg"; const name = "Team"; const symbol = "sap"; const tokenDetails = "This is equity type of issuance"; const decimals = 18; const contact = "team@polymath.network"; + const STVRParameters = ["bool", "uint256", "bool"]; // Module key const delegateManagerKey = 1; @@ -110,169 +88,27 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { account_investor4 = accounts[9]; account_investor5 = accounts[5]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ - from: account_polymath - }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 2: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ - from: account_polymath - }); - // - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ - from: account_polymath - }); - - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { - from: account_polymath - }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - - // - // - // // STEP 2: Deploy the GeneralTransferManagerFactory - // - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactoryFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 4: Deploy the SingleTradeVolumeRestrictionManagerFactory - I_SingleTradeVolumeRestrictionManagerFactory = await SingleTradeVolumeRestrictionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_SingleTradeVolumeRestrictionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SingleTradeVolumeRestrictionManagerFactory contract was not deployed" - ); - - - P_SingleTradeVolumeRestrictionManagerFactory = await SingleTradeVolumeRestrictionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, { - from: account_polymath - }); - assert.notEqual( - P_SingleTradeVolumeRestrictionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SingleTradeVolumeRestrictionManagerFactory contract was not deployed" - ); - // - // - // // Step 6: Deploy the STFactory contract - // - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { - from: account_polymath - }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ - from: account_polymath - }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ - from: account_polymath - }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - // - // // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { - from: account_polymath - }) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { - from: account_polymath - }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { - from: account_polymath - }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { - from: account_polymath - }); - await I_MRProxied.updateFromRegistry({ - from: account_polymath - }); - - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { - from: account_polymath - }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { - from: account_polymath - }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { - from: account_polymath - }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { - from: account_polymath - }); - - // (C) : Register the SingleTradeVolumeRestrictionManagerFactory - await I_MRProxied.registerModule(I_SingleTradeVolumeRestrictionManagerFactory.address, { - from: account_polymath - }); - await I_MRProxied.verifyModule(I_SingleTradeVolumeRestrictionManagerFactory.address, true, { - from: account_polymath - }); - - // (C) : Register the Paid SingleTradeVolumeRestrictionManagerFactory - await I_MRProxied.registerModule(P_SingleTradeVolumeRestrictionManagerFactory.address, { - from: account_polymath - }); - await I_MRProxied.verifyModule(P_SingleTradeVolumeRestrictionManagerFactory.address, true, { - from: account_polymath - }); - }) + [I_SingleTradeVolumeRestrictionManagerFactory] = await deploySingleTradeVolumeRMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [P_SingleTradeVolumeRestrictionManagerFactory] = await deploySingleTradeVolumeRMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); + + }); describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { @@ -375,63 +211,22 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { }); // it("Fails to attach the SingleTradeVolumeRestrictionManager with the security token due to fees not paid", async () => { - let managerArgs = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'bool', - name: '_isTransferLimitInPercentage' - }, - { - type: 'uint256', - name: '_globalTransferLimitInPercentageOrToken' - }, - { - type: 'bool', - name: '_allowPrimaryIssuance' - } - ] - }, [true, 90, false]) - let errorThrown = false; + let managerArgs = encodeModuleCall(STVRParameters, [true, 90, false]); + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, web3.utils.toWei("500", "ether"), 0, { - from: token_owner - }); - } catch (error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.addModule(P_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, web3.utils.toWei("500", "ether"), 0, { from: token_owner}) + ); }); - - it("Should successfully attach the Paid SingleTradeVolumeRestrictionManager with the security token", async () => { - let managerArgs = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'bool', - name: '_isTransferLimitInPercentage' - }, - { - type: 'uint256', - name: '_globalTransferLimitInPercentageOrToken' - }, - { - type: 'bool', - name: '_allowPrimaryIssuance' - } - ] - }, [false, 90, false]); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { - from: token_owner - }); + let managerArgs = encodeModuleCall(STVRParameters, [false, 90, false]); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + let tx = await I_SecurityToken.addModule(P_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "SingleTradeVolumeRestrictionManager did not get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) @@ -443,27 +238,11 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { }); it("Should successfully attach the SingleTradeVolumeRestrictionManager with the security token", async () => { - let managerArgs = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'bool', - name: '_isTransferLimitInPercentage' - }, - { - type: 'uint256', - name: '_globalTransferLimitInPercentageOrToken' - }, - { - type: 'bool', - name: '_allowPrimaryIssuance' - } - ] - }, [false, 7 * 10 ** 16, false]) + let managerArgs = encodeModuleCall(STVRParameters, [false, (7 * Math.pow(10, 16)).toString(), false]) const tx = await I_SecurityToken.addModule(I_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, 0, 0, { from: token_owner }); - assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); + assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "TransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), @@ -474,23 +253,7 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { }); it("Should successfully attach the SingleTradeVolumeRestrictionManager (Percentage) with the security token", async () => { - let managerArgs = web3.eth.abi.encodeFunctionCall({ - name: 'configure', - type: 'function', - inputs: [{ - type: 'bool', - name: '_isTransferLimitInPercentage' - }, - { - type: 'uint256', - name: '_globalTransferLimitInPercentageOrToken' - }, - { - type: 'bool', - name: '_allowPrimaryIssuance' - } - ] - }, [true, 90, false]); + let managerArgs = encodeModuleCall(STVRParameters, [true, 90, false]); const tx = await I_SecurityToken.addModule(I_SingleTradeVolumeRestrictionManagerFactory.address, managerArgs, 0, 0, { from: token_owner }); @@ -514,26 +277,14 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { ); }); - it('add exempt wallet', async () => { - let errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.addExemptWallet(accounts[5]); - } catch (e) { - errorThrown = true; - } - assert.ok(errorThrown, "Non Admins cannot add exempt wallets"); - - errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.addExemptWallet(zero_address, { - from: token_owner - }); - } catch (e) { - ensureException(e); - errorThrown = true; - } + it("add exempt wallet -- Not authorised ", async () => { + await catchRevert ( + I_SingleTradeVolumeRestrictionManager.addExemptWallet(accounts[5]) + ); - assert.ok(errorThrown, "Exempt wallet cannot be zero"); + await catchRevert( + I_SingleTradeVolumeRestrictionManager.addExemptWallet(zero_address, { from: token_owner }) + ); let tx = await I_SingleTradeVolumeRestrictionManager.addExemptWallet(accounts[5], { from: token_owner @@ -541,123 +292,67 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal(tx.logs[0].args._wallet, accounts[5], "Wrong wallet added as exempt"); }); - it('should remove an exempt wallet', async () => { - let errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.removeExemptWallet(accounts[5]); - } catch (e) { - errorThrown = true; - } - assert.ok(errorThrown, "Non Admins cannot add exempt wallets"); - - errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.removeExemptWallet(zero_address, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - - assert.ok(errorThrown, "Zero address cannot be added to exempt wallet"); + it("Should remove an exempt wallet", async () => { + await catchRevert ( + I_SingleTradeVolumeRestrictionManager.removeExemptWallet(accounts[5]) + ); + // 0 address are not allowed to add + await catchRevert ( + I_SingleTradeVolumeRestrictionManager.removeExemptWallet(zero_address, { from: token_owner }) + ); - let tx = await I_SingleTradeVolumeRestrictionManager.removeExemptWallet(accounts[5], { - from: token_owner - }); + let tx = await I_SingleTradeVolumeRestrictionManager.removeExemptWallet(accounts[5], { from: token_owner }); assert.equal(tx.logs[0].args._wallet, accounts[5], "Wrong wallet removed from exempt"); }); it('should set transfer limit for a wallet', async () => { - let errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 100); - } catch (e) { - errorThrown = true; - } - assert.ok(errorThrown, "Non Admins cannot set transfer limits"); + await catchRevert ( + I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 100) + ); + + // Transfer limits can't be set to 0 + await catchRevert ( + I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 0, { from: token_owner }) + ); + + // Transfer limit cannot be set in percentage + await catchRevert( + I_SingleTradeVolumeRestrictionManager.setTransferLimitInPercentage(accounts[4], 10, { from: token_owner }) + ); - errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 0, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Transfer limit cannot be set to 0") - errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInPercentage(accounts[4], 10, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Transfer limit cannot be set in percentage") let tx = await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(accounts[4], 100, { from: token_owner }); assert.equal(tx.logs[0].args._wallet, accounts[4]); assert.equal(tx.logs[0].args._amount, 100); - errorThrown = false; - try { - tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 0, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - errorThrown = false - try { - tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 101 * 10 ** 16, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Transfer limit can not be set to more 0") - errorThrown = false; - try { - tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInTokens(accounts[4], 1, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 0, { from: token_owner }) + ); + // Transfer limit can not be set to more 0 + await catchRevert ( + I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 101 * 10 ** 16, { from: token_owner }) + ); + // Transfer limit in tokens can not be set for a manager that has transfer limit set as percentage + await catchRevert ( + I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInTokens(accounts[4], 1, { from: token_owner }) + ); - assert.ok(errorThrown, "Transfer limit in tokens can not be set for a manager that has transfer limit set as percentage") - tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 50, { - from: token_owner - }); + tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(accounts[4], 50, { from: token_owner }); assert.equal(tx.logs[0].args._wallet, accounts[4], "Wrong wallet added to transfer limits"); assert.equal(tx.logs[0].args._percentage, 50, "Wrong percentage set"); }); it('should remove transfer limit for wallet', async () => { - let errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[4]); - } catch (e) { - errorThrown = true; - } - assert.ok(errorThrown, "Non Admins cannot set/remove transfer limits"); + // Non Admins cannot set/remove transfer limits + await catchRevert ( + I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[4]) + ); - errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[0], { - from: token_owner - }); - } catch (e) { - errorThrown = true; - } - assert.ok(errorThrown, "Non Admins cannot set/remove transfer limits"); + // Non Admins cannot set/remove transfer limits + await catchRevert ( + I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[0], { from: token_owner }) + ); let tx = await I_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokens(accounts[4], { from: token_owner @@ -671,128 +366,63 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { }); }); - it('should be able to set a global transfer limit', async () => { - let errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(100 * 10 ** 18); - } catch (e) { - errorThrown = true; - } - assert.ok(errorThrown, "only owner is allowed"); - - errorThrown = false; - - try { - let tx = await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInPercentage(100 * 10 ** 18, { - from: token_owner - }); - } catch (e) { - ensureException(e); - errorThrown = true; - } - assert.ok(errorThrown, "Cannot change global limit in percentage when set to tokens"); + it('Should be able to set a global transfer limit', async () => { + // only owner is allowed + await catchRevert( + I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(100 * 10 ** 18) + ); + //Cannot change global limit in percentage when set to tokens + await catchRevert( + I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInPercentage(100 * 10 ** 18, { from: token_owner }) + ); + // Global limit cannot be set to 0 + await catchRevert( + I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(0, { from: token_owner }) + ); - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(0, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Global limit cannot be set to 0"); let tx = await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(10, { from: token_owner }); assert.equal(tx.logs[0].args._amount, 10, "Global Limit not set"); + + //Global limit can be set by non-admins + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(89) + ); + // cannot change global limit in tokens if transfer limit is set to percentage + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(89, { from: token_owner }) + ); + // Cannot set global limit in tokens to 0 + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(0, { from: token_owner }) + ); - errorThrown = false; - - try { - let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(89); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Global limit can be set by non-admins"); - - errorThrown = false; - - try { - let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(89, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "cannot change global limit in tokens if transfer limit is set to percentage"); - - errorThrown = false; - try { - let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(0, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Cannot set global limit in tokens to 0"); - - tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInPercentage(40, { - from: token_owner - }); + tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInPercentage(40, { from: token_owner }); assert.equal(tx.logs[0].args._percentage, 40, "Global Limit not set"); - - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInPercentage(101 * 10 ** 16, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Global limit cannot be set to more than 100"); - - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInPercentage(10, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Global limit in percentage cannot be set when limit is in tokens"); - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(10, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Global limit in tokens cannot be set when limit is in percentage"); + // Global limit cannot be set to more than 100 + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInPercentage(101 * 10 ** 16, { from: token_owner }) + ); + // Global limit in percentage cannot be set when limit is in tokens + await catchRevert( + I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInPercentage(10, { from: token_owner }) + ); + // Global limit in tokens cannot be set when limit is in percentage + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.changeGlobalLimitInTokens(10, { from: token_owner }) + ); }); - it('should perform batch updates', async () => { + it("Should perform batch updates", async () => { let wallets = [accounts[0], accounts[1], accounts[2]]; let tokenLimits = [1, 2, 3]; let percentageLimits = [5, 6, 7]; - let errorThrown = false; - try { - await P_SingleTradeVolumeRestrictionManager.addExemptWalletMulti([], { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Exempt wallet multi cannot be empty wallet"); + // Exempt wallet multi cannot be empty wallet + await catchRevert( + P_SingleTradeVolumeRestrictionManager.addExemptWalletMulti([], { from: token_owner }) + ); // add exempt wallet multi let tx = await P_SingleTradeVolumeRestrictionManager.addExemptWalletMulti(wallets, { @@ -804,16 +434,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal(logs[i].args._wallet, wallets[i], "Wallet not added as exempt wallet"); } - errorThrown = false; - try { - await P_SingleTradeVolumeRestrictionManager.removeExemptWalletMulti([], { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Exempt wallet multi cannot be empty wallet"); + // Exempt wallet multi cannot be empty wallet + await catchRevert( + P_SingleTradeVolumeRestrictionManager.removeExemptWalletMulti([], { from: token_owner }) + ); // remove exempt wallet multi tx = await P_SingleTradeVolumeRestrictionManager.removeExemptWalletMulti(wallets, { @@ -825,28 +449,14 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { for (let i = 0; i < logs.length; i++) { assert.equal(logs[i].args._wallet, wallets[i], "Wallet not added as exempt wallet"); } - - errorThrown = false; - try { - tx = await P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti([], tokenLimits, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "wallets cannot be empty"); - - errorThrown = false; - try { - tx = await P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti([accounts[0]], tokenLimits, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "wallet array length dont match"); + // wallets cannot be empty + await catchRevert( + P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti([], tokenLimits, { from: token_owner }) + ); + // wallet array length dont match + await catchRevert( + P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti([accounts[0]], tokenLimits, { from: token_owner }) + ); tx = await P_SingleTradeVolumeRestrictionManager.setTransferLimitInTokensMulti(wallets, tokenLimits, { from: token_owner @@ -857,16 +467,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal(logs[i].args._wallet, wallets[i], "transfer limit not set for wallet"); assert.equal(logs[i].args._amount.toNumber(), tokenLimits[i]); } - errorThrown = false - try { - await P_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokensMulti([], { - from: token_owner - }); - } catch (e) { - ensureException(e); - errorThrown = true; - } - assert.ok(errorThrown, "Wallets cannot be empty"); + // Wallets cannot be empty + await catchRevert( + P_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokensMulti([], { from: token_owner }) + ); tx = await P_SingleTradeVolumeRestrictionManager.removeTransferLimitInTokensMulti(wallets, { from: token_owner }); @@ -875,28 +479,14 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { for (let i = 0; i < wallets.length; i++) { assert.equal(logs[i].args._wallet, wallets[i], "transfer limit not removed for wallet"); } - - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti([], percentageLimits, { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "wallets cannot be empty"); - - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti(wallets, [], { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "wallets and amounts dont match be empty"); + // wallets cannot be empty + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti([], percentageLimits, { from: token_owner }) + ); + // wallets and amounts dont match be empty + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti(wallets, [], { from: token_owner }) + ); tx = await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentageMulti(wallets, percentageLimits, { from: token_owner }); @@ -907,17 +497,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal(logs[i].args._wallet, wallets[i], "Transfer limit not set for wallet"); assert.equal(logs[i].args._percentage.toNumber(), percentageLimits[i]); } - - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentageMulti([], { - from: token_owner - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Wallets cannot be empty"); + // Wallets cannot be empty + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentageMulti([], { from: token_owner }) + ); tx = await I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentageMulti(wallets, { from: token_owner @@ -928,17 +511,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { for (let i = 0; i < wallets.length; i++) { assert.equal(logs[i].args._wallet, wallets[i], "Transfer limit not set for wallet"); } - - errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentage(wallets[0], { - from: token_owner - }); - } catch (e) { - ensureException(e) - errorThrown = true; - } - assert.ok(errorThrown, "Wallet should not be removed"); + // Wallet should not be removed + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.removeTransferLimitInPercentage(wallets[0], { from: token_owner }) + ); }) it('should be able to transfer tokens SingleTradeVolumeRestriction', async () => { @@ -987,17 +563,11 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { await I_SingleTradeVolumeRestrictionManager.changeGlobalLimitInTokens(web3.utils.toWei('5', 'ether'), { from: token_owner }) + // Transfer should have not happened + await catchRevert( + I_SecurityToken.transfer(account_investor3, web3.utils.toWei('6', 'ether'), { from: account_investor1 }) + ); - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('6', 'ether'), { - from: account_investor1 - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Transfer should have not happened"); await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); @@ -1016,16 +586,12 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { await I_SingleTradeVolumeRestrictionManager.setTransferLimitInTokens(account_investor5, web3.utils.toWei('5', 'ether'), { from: token_owner }); - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('7', 'ether'), { - from: account_investor5 - }); - } catch (e) { - errorThrown = true; - ensureException(e); - } - assert.ok(errorThrown, "Transfer should have not happened"); + + // Transfer should have not happened + await catchRevert( + I_SecurityToken.transfer(account_investor4, web3.utils.toWei('7', 'ether'), { from: account_investor5 }) + ); + await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('4', 'ether'), { from: account_investor5 }) @@ -1067,18 +633,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { from: token_owner }); - let errorThrown = false; - try { - // more than the limit - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('90', 'ether'), { - from: account_investor1 - }); - } catch (e) { - ensureException(e); - errorThrown = true; - } - assert.ok(errorThrown, "Transfer above limit happened"); - + // Transfer above limit happened + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei('90', 'ether'), { from: account_investor1 }) + ); await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('20', 'ether'), { from: account_investor1 @@ -1088,16 +646,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { await I_SingleTradeVolumeRestrictionPercentageManager.setTransferLimitInPercentage(account_investor1, 5 * 10 ** 16, { from: token_owner }); - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('35', 'ether'), { - from: account_investor1 - }); - } catch (e) { - ensureException(e); - errorThrown = true; - } - assert.ok(errorThrown, "transfer happened above limit"); + // transfer happened above limit + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei('35', 'ether'), { from: account_investor1 }) + ); await I_SecurityToken.transfer(account_investor3, web3.utils.toWei('1', 'ether'), { from: account_investor1 @@ -1106,17 +658,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { }); it('should change transfer limits to tokens', async () => { - let errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionPercentageManager.changeTransferLimitToPercentage(1, { - from: token_owner - }); - } catch (e) { - - ensureException(e); - errorThrown = true; - } - assert.equal(errorThrown, true, "Should not change to percentage again"); + // Should not change to percentage again + await catchRevert( + I_SingleTradeVolumeRestrictionPercentageManager.changeTransferLimitToPercentage(1, { from: token_owner }) + ); let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeTransferLimitToTokens(1, { @@ -1127,16 +672,10 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { }) it('should change transfer limits to percentage', async () => { - let errorThrown = false; - try { - await I_SingleTradeVolumeRestrictionManager.changeTransferLimitToTokens(1, { - from: token_owner - }); - } catch (e) { - ensureException(e); - errorThrown = true; - } - assert.equal(errorThrown, true, "Should not change to tokens again"); + // Should not change to tokens again + await catchRevert( + I_SingleTradeVolumeRestrictionManager.changeTransferLimitToTokens(1, { from: token_owner }) + ); let tx = await I_SingleTradeVolumeRestrictionPercentageManager.changeTransferLimitToPercentage(1, { from: token_owner From ba3ca777a88c9721550d0308b8242a0ccfd634f9 Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 9 Oct 2018 13:17:10 +0530 Subject: [PATCH 109/142] remove the redundant code --- test/helpers/createInstances.js | 162 ++++-- test/n_security_token_registry.js | 1 - test/q_usd_tiered_sto_sim.js | 161 +----- test/s_v130_to_v140_upgrade.js | 155 +---- test/w_volume_restriction_transfer_manager.js | 528 +++++------------- 5 files changed, 289 insertions(+), 718 deletions(-) diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index c187ce4c4..76d0c59cc 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -11,6 +11,7 @@ const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpointFactory.sol"); const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); +const SingleTradeVolumeRestrictionManagerFactory = artifacts.require('./SingleTradeVolumeRestrictionManagerFactory.sol'); const PercentageTransferManagerFactory = artifacts.require("./PercentageTransferManagerFactory.sol"); const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory"); @@ -20,6 +21,7 @@ const STFactory = artifacts.require("./STFactory.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); +const VolumeRestrictionTransferManagerFactory = artifacts.require("./VolumeRestrictionTransferManagerFactory"); const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); const PolyToken = artifacts.require("./PolyToken.sol"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); @@ -31,7 +33,9 @@ const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Contract Instance Declaration let I_USDTieredSTOProxyFactory; let I_USDTieredSTOFactory; +let I_SingleTradeVolumeRestrictionManagerFactory; let I_ManualApprovalTransferManagerFactory; +let I_VolumeRestrictionTransferManagerFactory; let I_PercentageTransferManagerFactory; let I_EtherDividendCheckpointFactory; let I_CountTransferManagerFactory; @@ -178,19 +182,7 @@ async function registerAndVerifyByMR(factoryAdrress, owner, mr) { await mr.verifyModule(factoryAdrress, true, { from: owner }); } -export async function deployGPMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralPermissionManagerFactory contract was not deployed" - ); - - // (B) : Register the GeneralDelegateManagerFactory - await registerAndVerifyByMR(I_GeneralPermissionManagerFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_GeneralPermissionManagerFactory); -} +/// Deploy the TransferManagers export async function deployGTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); @@ -206,92 +198,109 @@ export async function deployGTMAndVerifyed(accountPolymath, MRProxyInstance, pol return new Array(I_GeneralTransferManagerFactory); } - -export async function deployDummySTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_DummySTOFactory = await DummySTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); +export async function deployCountTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_CountTransferManagerFactory = await CountTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( - I_DummySTOFactory.address.valueOf(), + I_CountTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" + "CountTransferManagerFactory contract was not deployed" ); - await registerAndVerifyByMR(I_DummySTOFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_DummySTOFactory); -} -export async function deployERC20DividendAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + await registerAndVerifyByMR(I_CountTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_CountTransferManagerFactory); +} +export async function deployManualApprovalTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( - I_ERC20DividendCheckpointFactory.address.valueOf(), + I_ManualApprovalTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "ERC20DividendCheckpointFactory contract was not deployed" + "ManualApprovalTransferManagerFactory contract was not deployed" ); - await registerAndVerifyByMR(I_ERC20DividendCheckpointFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_ERC20DividendCheckpointFactory); -} -export async function deployEtherDividendAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + await registerAndVerifyByMR(I_ManualApprovalTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_ManualApprovalTransferManagerFactory); +} +export async function deployPercentageTMAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( - I_EtherDividendCheckpointFactory.address.valueOf(), + I_PercentageTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "EtherDividendCheckpointFactory contract was not deployed" + "PercentageTransferManagerFactory contract was not deployed" ); - await registerAndVerifyByMR(I_EtherDividendCheckpointFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_EtherDividendCheckpointFactory); + await registerAndVerifyByMR(I_PercentageTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_PercentageTransferManagerFactory); } -export async function deployCountTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_CountTransferManagerFactory = await CountTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); - +export async function deployVolumeRTMAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_VolumeRestrictionTransferManagerFactory = await VolumeRestrictionTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( - I_CountTransferManagerFactory.address.valueOf(), + I_VolumeRestrictionTransferManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "CountTransferManagerFactory contract was not deployed" + "VolumeRestrictionTransferManagerFactory contract was not deployed" ); - await registerAndVerifyByMR(I_CountTransferManagerFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_CountTransferManagerFactory); + await registerAndVerifyByMR(I_VolumeRestrictionTransferManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_VolumeRestrictionTransferManagerFactory); } -export async function deployCappedSTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_CappedSTOFactory = await CappedSTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); +export async function deploySingleTradeVolumeRMAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_SingleTradeVolumeRestrictionManagerFactory = await SingleTradeVolumeRestrictionManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( - I_CappedSTOFactory.address.valueOf(), + I_SingleTradeVolumeRestrictionManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" + "SingleTradeVolumeRestrictionManagerFactory contract was not deployed" ); - await registerAndVerifyByMR(I_CappedSTOFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_CappedSTOFactory); - + await registerAndVerifyByMR(I_SingleTradeVolumeRestrictionManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_SingleTradeVolumeRestrictionManagerFactory); } -export async function deployManualApprovalTMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_ManualApprovalTransferManagerFactory = await ManualApprovalTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); +/// Deploy the Permission Manager + +export async function deployGPMAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + assert.notEqual( - I_ManualApprovalTransferManagerFactory.address.valueOf(), + I_GeneralPermissionManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "ManualApprovalTransferManagerFactory contract was not deployed" + "GeneralPermissionManagerFactory contract was not deployed" ); - await registerAndVerifyByMR(I_ManualApprovalTransferManagerFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_ManualApprovalTransferManagerFactory); + // (B) : Register the GeneralDelegateManagerFactory + await registerAndVerifyByMR(I_GeneralPermissionManagerFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_GeneralPermissionManagerFactory); } -export async function deployPercentageTMAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { - I_PercentageTransferManagerFactory = await PercentageTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + +/// Deploy the STO Modules + +export async function deployDummySTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_DummySTOFactory = await DummySTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + assert.notEqual( - I_PercentageTransferManagerFactory.address.valueOf(), + I_DummySTOFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "PercentageTransferManagerFactory contract was not deployed" + "DummySTOFactory contract was not deployed" ); + await registerAndVerifyByMR(I_DummySTOFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_DummySTOFactory); +} + +export async function deployCappedSTOAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_CappedSTOFactory = await CappedSTOFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + assert.notEqual( + I_CappedSTOFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "CappedSTOFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_CappedSTOFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_CappedSTOFactory); - await registerAndVerifyByMR(I_PercentageTransferManagerFactory.address, accountPolymath, MRProxyInstance); - return new Array(I_PercentageTransferManagerFactory); } export async function deployPresaleSTOAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { @@ -323,6 +332,39 @@ export async function deployUSDTieredSTOAndVerified(accountPolymath, MRProxyInst } +/// Deploy the Dividend Modules + +export async function deployERC20DividendAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_ERC20DividendCheckpointFactory = await ERC20DividendCheckpointFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_ERC20DividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "ERC20DividendCheckpointFactory contract was not deployed" + ); + await registerAndVerifyByMR(I_ERC20DividendCheckpointFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_ERC20DividendCheckpointFactory); +} + +export async function deployEtherDividendAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_EtherDividendCheckpointFactory = await EtherDividendCheckpointFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_EtherDividendCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "EtherDividendCheckpointFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_EtherDividendCheckpointFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_EtherDividendCheckpointFactory); +} + + + + + + + /// Helper function function mergeReturn(returnData) { let returnArray = new Array(); diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 6bf13022c..dc5fc80d5 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -82,7 +82,6 @@ contract("SecurityTokenRegistry", accounts => { const newRegFee = web3.utils.toWei("300"); const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; const STOParameters = ["uint256", "uint256", "uint256", "string"]; // Capped STO details diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index e8c1b8a9f..53a12e74a 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -3,21 +3,12 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import { takeSnapshot, increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployUSDTieredSTOAndVerified } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); const USDTieredSTO = artifacts.require("./USDTieredSTO.sol"); const MockOracle = artifacts.require("./MockOracle.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); -const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); -const STFactory = artifacts.require("./STFactory.sol"); -const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory"); -const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); -const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); @@ -46,7 +37,6 @@ contract("USDTieredSTO Sim", accounts => { const GAS_PRICE = 10000000000; // 10 GWEI // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; let I_GeneralTransferManagerFactory; let I_USDTieredSTOProxyFactory; let I_SecurityTokenRegistryProxy; @@ -86,9 +76,6 @@ contract("USDTieredSTO Sim", accounts => { const USDETH = BigNumber(500).mul(10 ** 18); // 500 USD/ETH const USDPOLY = BigNumber(25).mul(10 ** 16); // 0.25 USD/POLY - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; - // STO Configuration Arrays let _startTime = []; let _endTime = []; @@ -190,115 +177,29 @@ contract("USDTieredSTO Sim", accounts => { NOTAPPROVED = accounts[8]; INVESTOR1 = accounts[9]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); I_DaiToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), ISSUER); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: POLYMATH - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 3: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 4: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the proxy - I_USDTieredSTOProxyFactory = await USDTieredSTOProxyFactory.new({ from: POLYMATH }); - - // STEP 6: Deploy the USDTieredSTOFactory - - I_USDTieredSTOFactory = await USDTieredSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, I_USDTieredSTOProxyFactory.address, { - from: ISSUER - }); - - assert.notEqual( - I_USDTieredSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "USDTieredSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - REGFEE, - REGFEE, - I_PolyToken.address, - POLYMATH - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: POLYMATH }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: POLYMATH }); - await I_MRProxied.updateFromRegistry({ from: POLYMATH }); - - // STEP 7: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_USDTieredSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_USDTieredSTOFactory.address, true, { from: POLYMATH }); + // Step:1 Create the polymath ecosystem contract instances + let instances = await setUpPolymathNetwork(POLYMATH, ISSUER); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + I_DaiToken = await PolyTokenFaucet.new({from: POLYMATH}); + + // STEP 5: Deploy the USDTieredSTOFactory + [I_USDTieredSTOFactory] = await deployUSDTieredSTOAndVerified(POLYMATH, I_MRProxied, I_PolyToken.address, STOSetupCost); // Step 12: Deploy & Register Mock Oracles I_USDOracle = await MockOracle.new(0, "ETH", "USD", USDETH, { from: POLYMATH }); // 500 dollars per POLY @@ -309,21 +210,19 @@ contract("USDTieredSTO Sim", accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} USDOracle: ${I_USDOracle.address} POLYOracle: ${I_POLYOracle.address} USDTieredSTOFactory: ${I_USDTieredSTOFactory.address} - USDTieredSTOProxyFactory: ${I_USDTieredSTOProxyFactory.address} ----------------------------------------------------------------------------- `); }); diff --git a/test/s_v130_to_v140_upgrade.js b/test/s_v130_to_v140_upgrade.js index c5c9cb8fc..8422dc6ee 100644 --- a/test/s_v130_to_v140_upgrade.js +++ b/test/s_v130_to_v140_upgrade.js @@ -5,8 +5,8 @@ const BigNumber = require("bignumber.js"); import latestTime from "./helpers/latestTime"; import { duration } from "./helpers/utils"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { setUpPolymathNetwork, deployCappedSTOAndVerifyed, deployGPMAndVerifyed } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory.sol"); const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); @@ -14,15 +14,7 @@ const USDTieredSTO = artifacts.require("./USDTieredSTO.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); const PolyOracle = artifacts.require("./PolyOracle.sol"); const ETHOracle = artifacts.require("./MakerDAOOracle.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); @@ -94,8 +86,6 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { let I_CappedSTO; let I_ManualApprovalTransferManagerFactory; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; const STOParameters = ["uint256", "uint256", "uint256", "uint256", "uint8[]", "address"]; // Prepare polymath network status before(async () => { @@ -105,117 +95,32 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { ISSUER2 = accounts[2]; ISSUER3 = accounts[3]; MULTISIG = accounts[4]; + + I_DaiToken = await PolyTokenFaucet.new({ from: POLYMATH }); // ----------- POLYMATH NETWORK Configuration ------------ - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: POLYMATH }); - assert.notEqual( - I_PolymathRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "PolymathRegistry contract was not deployed" - ); - - // Step 1: Deploy the token Faucet - I_PolyToken = await PolyTokenFaucet.new({ from: POLYMATH }); - I_DaiToken = await PolyTokenFaucet.new({ from: POLYMATH }); - assert.notEqual(I_PolyToken.address.valueOf(), "0x0000000000000000000000000000000000000000", "PolyToken contract was not deployed"); - tx = await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, "PolyToken"); - assert.equal(tx.logs[0].args._newAddress, I_PolyToken.address); - - // STEP 2: Deploy the ModuleRegistry - I_ModuleRegistry = await ModuleRegistry.new({ from: POLYMATH }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: POLYMATH }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, POLYMATH]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: POLYMATH }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - tx = await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: POLYMATH }); - assert.equal(tx.logs[0].args._nameKey, "ModuleRegistry"); - assert.equal(tx.logs[0].args._newAddress, I_ModuleRegistryProxy.address); - - // STEP 3: Deploy the GeneralTransferManagerFactory - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + let instances = await setUpPolymathNetwork(POLYMATH, ISSUER1); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 4: Deploy the GeneralDelegateManagerFactory - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(POLYMATH, I_MRProxied, I_PolyToken.address, 0); // STEP 5: Deploy the CappedSTOFactory - I_CappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); - assert.notEqual( - I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "CappedSTOFactory contract was not deployed" - ); - - // Step 8: Deploy the STFactory contract - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 9: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: POLYMATH }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 10: update the registries addresses from the PolymathRegistry contract - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: POLYMATH }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - REGFEE, - REGFEE, - I_PolyToken.address, - POLYMATH - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: POLYMATH }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // 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_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_STRProxied.address, { from: POLYMATH }); - await I_MRProxied.updateFromRegistry({ from: POLYMATH }); - - // STEP 6: Register the Modules with the ModuleRegistry contract - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: POLYMATH }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: POLYMATH }); - - // (C) : Register the CappedSTOFactory - await I_MRProxied.registerModule(I_CappedSTOFactory.address, { from: POLYMATH }); - await I_MRProxied.verifyModule(I_CappedSTOFactory.address, true, { from: POLYMATH }); + [I_CappedSTOFactory] = await deployCappedSTOAndVerifyed(POLYMATH, I_MRProxied, I_PolyToken.address, STOSetupCost); // Step 12: Mint tokens to ISSUERs await I_PolyToken.getTokens(REGFEE * 2, ISSUER1); @@ -257,16 +162,16 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} SecurityToken TOK1: ${I_SecurityToken1.address} SecurityToken TOK2: ${I_SecurityToken2.address} diff --git a/test/w_volume_restriction_transfer_manager.js b/test/w_volume_restriction_transfer_manager.js index b117511c8..fdef2a0ae 100644 --- a/test/w_volume_restriction_transfer_manager.js +++ b/test/w_volume_restriction_transfer_manager.js @@ -1,23 +1,14 @@ import latestTime from './helpers/latestTime'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; +import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; +import { setUpPolymathNetwork, deployVolumeRTMAndVerified } from "./helpers/createInstances"; +import { catchRevert } from "./helpers/exceptions"; -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const VolumeRestrictionTransferManagerFactory = artifacts.require('./VolumeRestrictionTransferManagerFactory.sol'); const VolumeRestrictionTransferManager = artifacts.require('./VolumeRestrictionTransferManager'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); @@ -42,7 +33,6 @@ contract('VolumeRestrictionTransferManager', accounts => { let message = "Transaction Should Fail!"; // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; let P_VolumeRestrictionTransferManagerFactory; let I_SecurityTokenRegistryProxy; let P_VolumeRestrictionTransferManager; @@ -77,9 +67,6 @@ contract('VolumeRestrictionTransferManager', accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - before(async() => { // Accounts setup account_polymath = accounts[0]; @@ -91,134 +78,39 @@ contract('VolumeRestrictionTransferManager', accounts => { account_investor2 = accounts[8]; account_investor3 = accounts[9]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4(a): Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 4(b): Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; // STEP 4(c): Deploy the VolumeRestrictionTransferManager - I_VolumeRestrictionTransferManagerFactory = await VolumeRestrictionTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_VolumeRestrictionTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "VolumeRestrictionTransferManagerFactory contract was not deployed" - ); - + [I_VolumeRestrictionTransferManagerFactory] = await deployVolumeRTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); // STEP 4(d): Deploy the VolumeRestrictionTransferManager - P_VolumeRestrictionTransferManagerFactory = await VolumeRestrictionTransferManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500", "ether"), 0, 0, {from:account_polymath}); - assert.notEqual( - P_VolumeRestrictionTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "VolumeRestrictionTransferManagerFactory contract was not deployed" - ); - - - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the VolumeRestrictionTransferManagerFactory - await I_MRProxied.registerModule(I_VolumeRestrictionTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_VolumeRestrictionTransferManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the Paid VolumeRestrictionTransferManagerFactory - await I_MRProxied.registerModule(P_VolumeRestrictionTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_VolumeRestrictionTransferManagerFactory.address, true, { from: account_polymath }); + [P_VolumeRestrictionTransferManagerFactory] = await deployVolumeRTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} VolumeRestrictionTransferManagerFactory: ${I_VolumeRestrictionTransferManagerFactory.address} ----------------------------------------------------------------------------- `); @@ -314,17 +206,11 @@ contract('VolumeRestrictionTransferManager', accounts => { ); }); - it("Should unsuccessfully attach the VolumeRestrictionTransferManager factory with the security token", async () => { - let errorThrown = false; + it("Should unsuccessfully attach the VolumeRestrictionTransferManager factory with the security token -- failed because Token is not paid", async () => { await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_VolumeRestrictionTransferManagerFactory.address, 0, web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.addModule(P_VolumeRestrictionTransferManagerFactory.address, 0, web3.utils.toWei("500", "ether"), 0, { from: token_owner }) + ) }); it("Should successfully attach the VolumeRestrictionTransferManager factory with the security token", async () => { @@ -398,117 +284,74 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should prevent the creation of a lockup with bad parameters where the totalAmount is zero", async() => { - let errorThrown = false; - try { - // create a lockup - // this will generate an exception because the totalAmount is zero - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, 0, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> couldn't create lock up because totalAmount is zero`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + // create a lockup + // this will generate an exception because the totalAmount is zero + await catchRevert( + I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, 0, { from: token_owner }) + ) }); it("Should prevent the creation of a lockup with bad parameters where the releaseFrequencySeconds is zero", async() => { - let errorThrown = false; - try { - // create a lockup - // this will generate an exception because the releaseFrequencySeconds is zero - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 0, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> couldn't create lock up because releaseFrequencySeconds is zero`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + // create a lockup + // this will generate an exception because the releaseFrequencySeconds is zero + await catchRevert( + I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 0, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }) + ); }); it("Should prevent the creation of a lockup with bad parameters where the lockUpPeriodSeconds is zero", async() => { - let errorThrown = false; - try { - // create a lockup - // this will generate an exception because the lockUpPeriodSeconds is zero - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 0, 4, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> couldn't create lock up because lockUpPeriodSeconds is zero`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + // create a lockup + // this will generate an exception because the lockUpPeriodSeconds is zero + await catchRevert( + I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 0, 4, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }) + ); }); it("Should prevent the creation of a lockup with bad parameters where the total amount to be released is more granular than allowed by the token", async() => { - let errorThrown = false; - try { - // create a lockup - // this will generate an exception because we're locking up 5e17 tokens but the granularity is 5e18 tokens - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, web3.utils.toWei('0.5', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> couldn't create lock up because the total amount to be released is more granular than allowed by the token`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + // create a lockup + // this will generate an exception because we're locking up 5e17 tokens but the granularity is 5e18 tokens + await catchRevert( + I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, web3.utils.toWei('0.5', 'ether'), { from: token_owner }) + ); }); - it("Should prevent the creation of a lockup with bad parameters where the lockUpPeriodSeconds is not evenly divisible by releaseFrequencySeconds", async() => { // balance should be 9000000000000000000 here (9 eth) let balance = await I_SecurityToken.balanceOf(account_investor2) - let errorThrown = false; - try { - // create a lockup - // over 17 seconds total, with 4 periods. - // this will generate an exception because 17 is not evenly divisble by 4. - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 17, 4, 0, balance, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> couldn't create lock up because lockUpPeriodSeconds must be evenly divisible by releaseFrequencySeconds`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + // create a lockup + // over 17 seconds total, with 4 periods. + // this will generate an exception because 17 is not evenly divisble by 4. + await catchRevert( + I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 17, 4, 0, balance, { from: token_owner }) + ); }); it("Should prevent the creation of a lockup with bad parameters where the total amount being locked up isn't evenly divisible by the number of total periods", async() => { - let errorThrown = false; - try { - // create a lockup for a balance of 1 eth - // over 16e18 seconds total, with 4e18 periods of 4 seconds each. - // this will generate an exception because 16e18 / 4e18 = 4e18 but the token granularity is 1e18 and 1e18 % 4e18 != 0 - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, web3.utils.toWei('16', 'ether'), 4, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }); - } catch(error) { - console.log(` tx revert -> couldn't create lock up because the total amount being locked up must be evenly divisible by the number of total periods`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + // create a lockup for a balance of 1 eth + // over 16e18 seconds total, with 4e18 periods of 4 seconds each. + // this will generate an exception because 16e18 / 4e18 = 4e18 but the token granularity is 1e18 and 1e18 % 4e18 != 0 + await catchRevert( + I_VolumeRestrictionTransferManager.addLockUp(account_investor2, web3.utils.toWei('16', 'ether'), 4, 0, web3.utils.toWei('1', 'ether'), { from: token_owner }) + ); }); it("Should prevent the creation of a lockup with bad parameters where the amount to be released per period is too granular for the token", async() => { // balance should be 9000000000000000000 here (9 eth) let balance = await I_SecurityToken.balanceOf(account_investor2) - - - let errorThrown = false; - try { - // create a lockup for their entire balance - // over 16 seconds total, with 4 periods of 4 seconds each. - // this will generate an exception because 9000000000000000000 / 4 = 2250000000000000000 but the token granularity is 1000000000000000000 - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, balance, { from: token_owner }); - } catch(error) { - console.log(` tx revert -> couldn't create lock up because amount to be released per period is more granular than allowed by the token`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + + // create a lockup for their entire balance + // over 16 seconds total, with 4 periods of 4 seconds each. + // this will generate an exception because 9000000000000000000 / 4 = 2250000000000000000 but the token granularity is 1000000000000000000 + await catchRevert( + I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 16, 4, 0, balance, { from: token_owner }) + ); + }); it("Should prevent the transfer of tokens in a lockup", async() => { @@ -524,16 +367,9 @@ contract('VolumeRestrictionTransferManager', accounts => { // enum Result {INVALID, NA, VALID, FORCE_VALID} and we want VALID so it should be 2 assert.equal(result.toString(), '0') - - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) + ); }); it("Should allow the transfer of tokens in a lockup if a period has passed", async() => { @@ -546,15 +382,9 @@ contract('VolumeRestrictionTransferManager', accounts => { it("Should prevent the transfer of tokens if the amount is larger than the amount allowed by lockups", async() => { - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('4', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('4', 'ether'), { from: account_investor2 }) + ); }); it("Should allow the transfer of more tokens in a lockup if another period has passed", async() => { @@ -589,15 +419,9 @@ contract('VolumeRestrictionTransferManager', accounts => { // console.log('blockNumber',blockNumber) let now = (await web3.eth.getBlock('latest')).timestamp - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }) + ); // check and get the lockup let lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor1); @@ -615,16 +439,9 @@ contract('VolumeRestrictionTransferManager', accounts => { await I_VolumeRestrictionTransferManager.modifyLockUp(account_investor1, 0, 8, 4, 0, balance, { from: token_owner }); // attempt a transfer - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('6', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei('6', 'ether'), { from: account_investor1 }) + ); // wait 4 seconds await new Promise(resolve => setTimeout(resolve, 4000)); @@ -634,19 +451,13 @@ contract('VolumeRestrictionTransferManager', accounts => { }); - it("Should be possible to remove a lockup", async() => { + it("Should be possible to remove a lockup -- couldn't transfer because of lock up", async() => { let acct1Balance = await I_SecurityToken.balanceOf(account_investor1) - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, acct1Balance, { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor2, acct1Balance, { from: account_investor1 }) + ); // check and get the lockup let lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor1); @@ -697,25 +508,13 @@ contract('VolumeRestrictionTransferManager', accounts => { { from: token_owner } ); - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor3 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }) + ); + + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor3 }) + ); let balancesAfter = {} balancesAfter[account_investor2] = await I_SecurityToken.balanceOf(account_investor2) @@ -751,23 +550,18 @@ contract('VolumeRestrictionTransferManager', accounts => { }); it("Should revert if the parameters are bad when creating multiple lockups", async() => { - let errorThrown = false; - try { + + await catchRevert( // pass in the wrong number of params. txn should revert - await I_VolumeRestrictionTransferManager.addLockUpMulti( + I_VolumeRestrictionTransferManager.addLockUpMulti( [account_investor2, account_investor3], [16, 8], [2], // this array should have 2 elements but it has 1, which should cause a revert [0, 0], [web3.utils.toWei('1', 'ether'), web3.utils.toWei('1', 'ether')], { from: token_owner } + ) ); - } catch(error) { - console.log(` tx revert -> passed in wrong number of array elements`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); }); it("Should be possible to create a lockup with a specific start time in the future", async() => { @@ -788,34 +582,20 @@ contract('VolumeRestrictionTransferManager', accounts => { await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 100, 10, now + 4, balance, { from: token_owner }); // try a transfer. it should fail because the lockup hasn't started yet. - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) + ); now = (await web3.eth.getBlock('latest')).timestamp // wait 4 seconds for the lockup to begin await new Promise(resolve => setTimeout(resolve, 4000)); // try another transfer. it should also fail because the lockup has just begun - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) + ); now = (await web3.eth.getBlock('latest')).timestamp - assert.ok(errorThrown, message); - }); it("Should be possible to edit a lockup with a specific start time in the future", async() => { @@ -854,29 +634,17 @@ contract('VolumeRestrictionTransferManager', accounts => { assert.equal(lockUp[3].toString(), balance.toString()); // try a transfer. it should fail because again, the lockup hasn't started yet. - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) + ); // wait 4 seconds for the lockup to begin await new Promise(resolve => setTimeout(resolve, 4000)); // try another transfer. it should fail because the lockup has just begun - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) + ); // wait 4 seconds for the lockup's first period to elapse await new Promise(resolve => setTimeout(resolve, 4000)); @@ -886,15 +654,9 @@ contract('VolumeRestrictionTransferManager', accounts => { // try another transfer without waiting for another period to pass. it should fail - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor2 }) + ); // wait 4 seconds for the lockup's first period to elapse await new Promise(resolve => setTimeout(resolve, 4000)); @@ -915,15 +677,9 @@ contract('VolumeRestrictionTransferManager', accounts => { await new Promise(resolve => setTimeout(resolve, 4000)); // try one final transfer. this should fail because the user has already withdrawn their entire balance - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) + ); }); it("Should be possible to stack lockups", async() => { @@ -940,16 +696,9 @@ contract('VolumeRestrictionTransferManager', accounts => { await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('11', 'ether'), { from: account_investor1 }); // try a transfer. it should fail because it's locked up from the first lockups - let errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }) + ); // wait 4 seconds for the lockup's first period to elapse. await new Promise(resolve => setTimeout(resolve, 4000)); @@ -964,15 +713,9 @@ contract('VolumeRestrictionTransferManager', accounts => { await I_VolumeRestrictionTransferManager.addLockUp(account_investor1, 16, 4, 0, web3.utils.toWei('8', 'ether'), { from: token_owner }); // try a transfer. it should fail because it's locked up from both lockups - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }) + ); // wait 4 seconds for the 1st lockup's second period to elapse, and the 2nd lockup's first period to elapse await new Promise(resolve => setTimeout(resolve, 4000)); @@ -981,15 +724,9 @@ contract('VolumeRestrictionTransferManager', accounts => { await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); // try aother transfer. it should fail because it's locked up from both lockups again - errorThrown = false; - try { - await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - } catch(error) { - console.log(` tx revert -> couldn't transfer because of lock up`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }) + ); // wait 4 seconds for the 1st lockup's final period to elapse, and the 2nd lockup's second period to elapse await new Promise(resolve => setTimeout(resolve, 4000)); @@ -997,17 +734,6 @@ contract('VolumeRestrictionTransferManager', accounts => { // should now be able to transfer 4, because of 2 allowed from the 1st lockup and 2 from the 2nd await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); - // // try aother transfer. it should fail because it's locked up from both lockups again - // errorThrown = false; - // try { - // await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); - // } catch(error) { - // console.log(` tx revert -> couldn't transfer because of lock up`.grey); - // ensureException(error); - // errorThrown = true; - // } - // assert.ok(errorThrown, message); - // wait 8 seconds for 2nd lockup's third and fourth periods to elapse await new Promise(resolve => setTimeout(resolve, 8000)); From e0a33023b41e74f39cd58ff170c9a44daa39ed2b Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 9 Oct 2018 14:01:23 +0530 Subject: [PATCH 110/142] improve the test code of proxies --- test/helpers/createInstances.js | 17 +++ test/t_security_token_registry_proxy.js | 95 ++++----------- test/u_module_registry_proxy.js | 90 +++++--------- test/v_tracked_redemptions.js | 156 +++++------------------- 4 files changed, 104 insertions(+), 254 deletions(-) diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 76d0c59cc..ff2a66f4b 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -12,6 +12,7 @@ const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpo const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); const SingleTradeVolumeRestrictionManagerFactory = artifacts.require('./SingleTradeVolumeRestrictionManagerFactory.sol'); +const TrackedRedemptionFactory = artifacts.require("./TrackedRedemptionFactory.sol"); const PercentageTransferManagerFactory = artifacts.require("./PercentageTransferManagerFactory.sol"); const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); const USDTieredSTOProxyFactory = artifacts.require("./USDTieredSTOProxyFactory"); @@ -33,6 +34,7 @@ const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Contract Instance Declaration let I_USDTieredSTOProxyFactory; let I_USDTieredSTOFactory; +let I_TrackedRedemptionFactory; let I_SingleTradeVolumeRestrictionManagerFactory; let I_ManualApprovalTransferManagerFactory; let I_VolumeRestrictionTransferManagerFactory; @@ -360,6 +362,21 @@ export async function deployEtherDividendAndVerifyed(accountPolymath, MRProxyIns } +/// Deploy the Burn Module + +export async function deployRedemptionAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_TrackedRedemptionFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "TrackedRedemptionFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_TrackedRedemptionFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_TrackedRedemptionFactory); +} + diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index d46d6f1f7..2d426d656 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -1,19 +1,14 @@ -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); -const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); const OwnedUpgradeabilityProxy = artifacts.require("./OwnedUpgradeabilityProxy.sol"); -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const STFactory = artifacts.require("./STFactory.sol"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -52,7 +47,6 @@ contract("SecurityTokenRegistryProxy", accounts => { const transferManagerKey = 2; const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; async function readStorage(contractAddress, slot) { return await web3.eth.getStorageAt(contractAddress, slot); @@ -64,78 +58,37 @@ contract("SecurityTokenRegistryProxy", accounts => { token_owner = accounts[2]; account_polymath_new = accounts[3]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // Register the Modules with the ModuleRegistry contract - - // Step 3: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); await I_MRProxied.updateFromRegistry({ from: account_polymath }); - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - + // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); }); diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index 7c8cf3a71..4ba4d12c6 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -1,20 +1,16 @@ -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork } from "./helpers/createInstances"; -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); -const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); -const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const MockModuleRegistry = artifacts.require("./MockModuleRegistry.sol"); const OwnedUpgradeabilityProxy = artifacts.require("./OwnedUpgradeabilityProxy.sol"); -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); const STFactory = artifacts.require("./STFactory.sol"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const FeatureRegistry = artifacts.require("./FeatureRegistry.sol"); +const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); +const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -53,7 +49,6 @@ contract("ModuleRegistryProxy", accounts => { const decimals = 18; const transferManagerKey = 2; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; const MRProxyParameters = ["address", "address"]; async function readStorage(contractAddress, slot) { @@ -66,58 +61,38 @@ contract("ModuleRegistryProxy", accounts => { token_owner = accounts[2]; account_polymath_new = accounts[3]; - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // Step 4: Deploy the SecurityTokenRegistry - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: account_polymath}); + I_ModuleRegistry = await ModuleRegistry.new({from: account_polymath }); - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} ----------------------------------------------------------------------------- `); }); @@ -130,7 +105,7 @@ contract("ModuleRegistryProxy", accounts => { it("Should attach the MR implementation and version", async () => { let bytesProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, { from: account_polymath }); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, { from: account_polymath }); let c = OwnedUpgradeabilityProxy.at(I_ModuleRegistryProxy.address); assert.equal(await readStorage(c.address, 12), I_ModuleRegistry.address); assert.equal( @@ -144,6 +119,7 @@ contract("ModuleRegistryProxy", accounts => { }); it("Deploy the essential smart contracts", async () => { + await I_MRProxied.updateFromRegistry({ from: account_polymath }); // STEP 4: Deploy the GeneralTransferManagerFactory I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index 9a2154c7b..b1af22535 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -1,24 +1,14 @@ import latestTime from "./helpers/latestTime"; -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployRedemptionAndVerifyed } from "./helpers/createInstances"; -const PolymathRegistry = artifacts.require("./PolymathRegistry.sol"); -const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); -const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); -const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); -const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.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"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const TrackedRedemptionFactory = artifacts.require("./TrackedRedemptionFactory.sol"); const TrackedRedemption = artifacts.require("./TrackedRedemption"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); -const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -78,8 +68,6 @@ contract("TrackedRedemption", accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; - const MRProxyParameters = ["address", "address"]; before(async () => { // Accounts setup @@ -96,123 +84,39 @@ contract("TrackedRedemption", accounts => { // ----------- POLYMATH NETWORK Configuration ------------ - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({ from: account_polymath }); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens(10000 * Math.pow(10, 18), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new(I_PolymathRegistry.address, { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({ from: account_polymath }); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({ from: account_polymath }); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, { from: account_polymath }); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { - from: account_polymath - }); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + + // STEP 4: Deploy the TrackedRedemption - I_TrackedRedemptionFactory = await TrackedRedemptionFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - assert.notEqual( - I_TrackedRedemptionFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "TrackedRedemptionFactory contract was not deployed" - ); - - // Step 6: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - - assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); - - // Step 7: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({ from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed" - ); - - // Step 8: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({ from: account_polymath }); - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - initRegFee, - I_PolyToken.address, - account_polymath - ]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 9: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, { from: account_polymath }); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, { from: account_polymath }); - await I_MRProxied.updateFromRegistry({ from: account_polymath }); - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the TrackedRedemptionFactory - await I_MRProxied.registerModule(I_TrackedRedemptionFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_TrackedRedemptionFactory.address, true, { from: account_polymath }); + [I_TrackedRedemptionFactory] = await deployRedemptionAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistry: ${I_ModuleRegistry.address} + ModuleRegistryProxy: ${I_ModuleRegistryProxy.address} + FeatureRegistry: ${I_FeatureRegistry.address} + + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} TrackedRedemptionFactory: ${I_TrackedRedemptionFactory.address} ----------------------------------------------------------------------------- From 4c32a99a978f92d27d9cd1b8ae9b7666c3dc4328 Mon Sep 17 00:00:00 2001 From: satyam Date: Tue, 9 Oct 2018 14:27:47 +0530 Subject: [PATCH 111/142] fix in GPM --- .../modules/PermissionManager/GeneralPermissionManager.sol | 1 + test/g_general_permission_manager.js | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 563778b12..21c93f02b 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -60,6 +60,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { */ function addDelegate(address _delegate, bytes32 _details) external withPerm(CHANGE_PERMISSION) { require(_details != bytes32(0), "0 value not allowed"); + require(delegateDetails[_delegate] == bytes32(0), "Already present"); delegateDetails[_delegate] = _details; allDelegates.push(_delegate); emit AddDelegate(_delegate, _details, now); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index c8fddf2b5..0cf090030 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -219,7 +219,7 @@ contract("GeneralPermissionManager", accounts => { }); it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async () => { - await catchRevert(I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: account_investor1 })); + await catchRevert(I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1 })); }); it("Should fail to provide the permission-- because delegate is not yet added", async () => { @@ -230,14 +230,11 @@ contract("GeneralPermissionManager", accounts => { ); }); - it("Should add the permission to the delegate", async () => { - let tx = await I_GeneralPermissionManager.addPermission(account_delegate, delegateDetails, { from: token_owner }); - }); - it("Should fail in adding the delegate -- msg.sender doesn't have permission", async() => { await catchRevert( I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}) ); + }); it("Should fail in adding the delegate -- no delegate details provided", async() => { await catchRevert( From d2f048bd8ddfabe31ebd09d218d6aaf59d51f2a2 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Tue, 9 Oct 2018 15:33:22 +0200 Subject: [PATCH 112/142] finished refacting module / added new function to allow active/deactive ballot --- .../Checkpoint/WeightedVoteCheckpoint.sol | 20 +- test/g_general_permission_manager.js | 12 +- test/weighted_vote_oct.js | 74 ++- test/weighted_vote_old.js | 461 ------------------ 4 files changed, 93 insertions(+), 474 deletions(-) delete mode 100644 test/weighted_vote_old.js diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol index 39de9e7bc..6ab4d8777 100644 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol @@ -20,6 +20,7 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { uint256 cumulativeNo; uint256 numVotes; mapping(address => Vote) voteByAddress; + bool isActive; } Ballot[] public ballots; @@ -32,6 +33,7 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { event BallotCreated(uint256 _startTime, uint256 _endTime, uint256 _ballotId, uint256 _checkpointId); event VoteCasted(uint256 _ballotId, uint256 _time, address indexed _investor, uint256 _weight, bool _vote); + event BallotDeactivated(uint256 _ballotId, bool _isActive); /** * @notice Constructor @@ -65,6 +67,7 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { function castVote(bool _vote, uint256 _ballotId) public returns (bool) { require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); require(ballots[_ballotId].voteByAddress[msg.sender].time == 0, "Token holder has already voted."); + require(ballots[_ballotId].isActive == true, "This ballot is deactiveated."); uint256 checkpointId = ballots[_ballotId].checkpointId; uint256 weight = ISecurityToken(securityToken).balanceOfAt(msg.sender,checkpointId); require(weight > 0, "Token Holder balance is zero."); @@ -91,7 +94,7 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); uint256 currentSupply = ISecurityToken(securityToken).totalSupply(); uint256 endTime = now.add(_duration); - ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0)); + ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0,true)); emit BallotCreated(now, endTime, ballotId, checkpointId); return true; } @@ -107,11 +110,24 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { require(_endTime >= _startTime); uint256 ballotId = ballots.length; uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); - ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0)); + ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0, true)); emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); return true; } + /** + * @notice Allows the token issuer to set the active stats of a ballot + * @param _ballotId The index of the target ballot + * @param _isActive The bool value of the active stats of the ballot + * @return bool success + */ + function setActiveStatsBallot(uint256 _ballotId, bool _isActive) public onlyOwner returns (bool) { + require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); + ballots[_ballotId].isActive = _isActive; + emit BallotDeactivated(_ballotId, _isActive); + return true; + } + // /** // * @notice Init function i.e generalise function to maintain the structure of the module contract // * @return bytes4 diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 32b501565..81b86a7c3 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -141,24 +141,24 @@ contract('GeneralPermissionManager', accounts => { "GeneralTransferManagerFactory contract was not deployed" ); - // STEP 5: Deploy the GeneralDelegateManagerFactory + // STEP 5: Deploy the GeneralPermissionManagerFactory I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" + "GeneralPermissionManagerFactory contract was not deployed" ); - // STEP 6: Deploy the GeneralDelegateManagerFactory + // STEP 6: Deploy the GeneralPermissionManagerFactory P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); assert.notEqual( P_GeneralPermissionManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" + "GeneralPermissionManagerFactory contract was not deployed" ); // STEP 7: Deploy the DummySTOFactory @@ -211,11 +211,11 @@ contract('GeneralPermissionManager', accounts => { await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralDelegateManagerFactory + // (B) : Register the GeneralPermissionManagerFactory await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the Paid GeneralDelegateManagerFactory + // (B) : Register the Paid GeneralPermissionManagerFactory await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); diff --git a/test/weighted_vote_oct.js b/test/weighted_vote_oct.js index 9d88ce873..6adbce5a0 100644 --- a/test/weighted_vote_oct.js +++ b/test/weighted_vote_oct.js @@ -65,7 +65,9 @@ contract('WeightedVoteCheckpoint', accounts => { let I_PolyToken; let I_PolymathRegistry; let I_WeightedVoteCheckpointFactory; + let P_WeightedVoteCheckpointFactory; let I_WeightedVoteCheckpoint; + let P_WeightedVoteCheckpoint; // SecurityToken Details const name = "Team"; @@ -147,8 +149,6 @@ contract('WeightedVoteCheckpoint', accounts => { ); // STEP 5: Deploy the WeightedVoteCheckpointFactory - - console.log("1"); I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); assert.notEqual( @@ -158,6 +158,16 @@ contract('WeightedVoteCheckpoint', accounts => { ); console.log("deployed weight vote factory to "+I_WeightedVoteCheckpointFactory.address); + // STEP 6: Deploy the WeightedVoteCheckpointFactory with fees + + P_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); + + assert.notEqual( + P_WeightedVoteCheckpointFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "WeightedVoteCheckpointFactory contract with fees was not deployed" + ); + // STEP 7: Deploy the DummySTOFactory I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); @@ -213,8 +223,8 @@ contract('WeightedVoteCheckpoint', accounts => { await I_MRProxied.verifyModule(I_WeightedVoteCheckpointFactory.address, true, { from: account_polymath }); // (B) : Register the Paid GeneralDelegateManagerFactory - // await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); - // await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); + await I_MRProxied.registerModule(P_WeightedVoteCheckpointFactory.address, { from: account_polymath }); + await I_MRProxied.verifyModule(P_WeightedVoteCheckpointFactory.address, true, { from: account_polymath }); // (C) : Register the STOFactory await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); @@ -274,11 +284,33 @@ contract('WeightedVoteCheckpoint', accounts => { I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); + it("Should fail to attach the WeightedVoteCheckpoint module to the security token if fee not paid", async () => { + let errorThrown = false; + await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); + try { + const tx = await I_SecurityToken.addModule(P_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because setup fee is not paid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should successfully attach the WeightedVoteCheckpoint module to the security token after fees been paid", async () => { + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + console.log("weightVoteFactory PAID Address is " + P_WeightedVoteCheckpointFactory.address); + console.log(tx.logs); + assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); + assert.equal(web3.utils.hexToUtf8(tx.logs[3].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); + P_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[3].args._module); + }); it("Should successfully attach the Weighted Vote Checkpoint factory with the security token", async () => { const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "0x", 0, 0, { from: token_owner }); console.log("weightVoteFactory Address is " + I_WeightedVoteCheckpointFactory.address); - console.log(tx.logs[2].args); + console.log(tx.logs); assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); assert.equal(web3.utils.hexToUtf8(tx.logs[2].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); I_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[2].args._module); @@ -298,6 +330,7 @@ contract('WeightedVoteCheckpoint', accounts => { gas: 500000 }); await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); + assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); }); it("Should successfully mint tokens for second investor account", async() => { @@ -312,6 +345,7 @@ contract('WeightedVoteCheckpoint', accounts => { gas: 500000 }); await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); + assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); }); }); @@ -429,6 +463,8 @@ contract('WeightedVoteCheckpoint', accounts => { it("Should successfully cast a vote from first investor", async() => { let tx = await I_WeightedVoteCheckpoint.castVote(false, 0, { from: account_investor1 }); + console.log(tx.logs); + assert.equal(tx.logs[0].args._investor, account_investor1, "Failed to record vote"); assert.equal(tx.logs[0].args._vote, false, "Failed to record vote"); assert.equal(tx.logs[0].args._weight, web3.utils.toWei('1', 'ether'), "Failed to record vote"); @@ -469,4 +505,32 @@ contract('WeightedVoteCheckpoint', accounts => { }); }); + describe("Active/Deactive Ballot", async() => { + + it("Should successfully deactive the ballot", async() => { + let tx = await I_WeightedVoteCheckpoint.setActiveStatsBallot(0, false, { from: token_owner }); + let tx2 = await I_WeightedVoteCheckpoint.ballots(0, { from: token_owner }); + assert.equal(tx2[7], false); + }); + + it("Should fail to cast a vote if ballot is deactivated", async() => { + let errorThrown = false; + try { + let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor1 }); + } catch(error) { + console.log(` tx -> failed because ballot is deactivated`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + + it("Should successfully active the same ballot again", async() => { + let tx = await I_WeightedVoteCheckpoint.setActiveStatsBallot(0, true, { from: token_owner }); + let tx2 = await I_WeightedVoteCheckpoint.ballots(0, { from: token_owner }); + assert.equal(tx2[7], true); + }); + }); + }); diff --git a/test/weighted_vote_old.js b/test/weighted_vote_old.js deleted file mode 100644 index 14e3b2a18..000000000 --- a/test/weighted_vote_old.js +++ /dev/null @@ -1,461 +0,0 @@ -import latestTime from './helpers/latestTime'; -import { duration, ensureException } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { error } from 'util'; - -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 STVersion = artifacts.require('./STVersionProxy001.sol'); -const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); -const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const WeightedVoteCheckpointFactory = artifacts.require('./WeightedVoteCheckpointFactory.sol'); -const WeightedVoteCheckpoint = artifacts.require('./WeightedVoteCheckpoint'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('WeightedVoteCheckpoint', accounts => { - - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_GeneralPermissionManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManagerFactory; - let I_GeneralTransferManager; - let I_WeightedVoteCheckpointFactory; - let I_WeightedVoteCheckpoint; - let I_ExchangeTransferManager; - let I_ModuleRegistry; - let I_TickerRegistry; - let I_SecurityTokenRegistry; - let I_STVersion; - let I_SecurityToken; - let I_PolyToken; - - // SecurityToken Details - const swarmHash = "dagwrgwgvwergwrvwrg"; - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - let snapId; - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - - // Initial fee for ticker registry and security token registry - const initRegFee = 250 * Math.pow(10, 18); - - before(async() => { - - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // STEP 1: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - - assert.notEqual( - I_ModuleRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "ModuleRegistry contract was not deployed" - ); - - // STEP 2: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 3: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - console.log("1"); - // STEP 4: Deploy the WeightedVoteCheckpointFactory - I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_WeightedVoteCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "WeightedVoteCheckpointFactory contract was not deployed" - ); - console.log("2"); - - // // Step 11: update the registries addresses from the PolymathRegistry contract - // await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - // await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - // await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - // await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - // await I_MRProxied.updateFromRegistry({from: account_polymath}); - - - // STEP 5: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_ModuleRegistry.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_ModuleRegistry.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_ModuleRegistry.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_ModuleRegistry.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the WeightedVoteCheckpointFactory - await I_ModuleRegistry.registerModule(I_WeightedVoteCheckpointFactory.address, { from: account_polymath }); - await I_ModuleRegistry.verifyModule(I_WeightedVoteCheckpointFactory.address, true, { from: account_polymath }); - - // Step 6: Deploy the TickerRegistry - - I_TickerRegistry = await TickerRegistry.new(I_PolyToken.address, initRegFee, { from: account_polymath }); - - assert.notEqual( - I_TickerRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "TickerRegistry contract was not deployed", - ); - - // Step 7: Deploy the STversionProxy contract - - I_STVersion = await STVersion.new(I_GeneralTransferManagerFactory.address); - - assert.notEqual( - I_STVersion.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STVersion contract was not deployed", - ); - - // Step 8: Deploy the SecurityTokenRegistry - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new( - I_PolyToken.address, - I_ModuleRegistry.address, - I_TickerRegistry.address, - I_STVersion.address, - initRegFee, - { - from: account_polymath - }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 8: Set the STR in TickerRegistry - await I_TickerRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistry.address, {from: account_polymath}); - await I_ModuleRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistry.address, {from: account_polymath}); - - // Printing all the contract addresses - console.log(`\nPolymathh Network Smart Contracts Deployed:\n - ModuleRegistry: ${I_ModuleRegistry.address}\n - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address}\n - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address}\n - WeightedVoteCheckpointFactory: ${I_WeightedVoteCheckpointFactory.address}\n - TickerRegistry: ${I_TickerRegistry.address}\n - STVersionProxy_001: ${I_STVersion.address}\n - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address}\n - `); - }); - - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_SecurityTokenRegistry.address, initRegFee, { from: token_owner }); - let tx = await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas: 85000000 }); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const LogAddModule = await I_SecurityToken.allEvents(); - const log = await new Promise(function(resolve, reject) { - LogAddModule.watch(function(error, log){ resolve(log);}); - }); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - LogAddModule.stopWatching(); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = await I_SecurityToken.modules(2, 0); - I_GeneralTransferManager = GeneralTransferManager.at(moduleData[1]); - - assert.notEqual( - I_GeneralTransferManager.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManager contract was not deployed", - ); - - }); - - it("Should fail to attach the WeightedVoteCheckpoint module to the security token if fee not paid", async () => { - let errorThrown = false; - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because setup fee is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully attach the WeightedVoteCheckpoint module to the security token", async () => { - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, true, { from: token_owner }); - assert.equal(tx.logs[3].args._type.toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); - assert.equal(web3.utils.hexToUtf8(tx.logs[3].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); - I_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[3].args._module); - }); - - }); - - describe("Preparation", async() => { - it("Should successfully mint tokens for first investor account", async() => { - await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - }); - - it("Should successfully mint tokens for second investor account", async() => { - await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - }); - }); - - describe("Create ballot", async() => { - - it("Should fail to create a new ballot if not owner", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: account_temp }); - } catch(error) { - console.log(` tx -> failed because msg.sender is not owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully create a new ballot", async() => { - let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: token_owner }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); - }); - }); - - describe("Create custom ballot", async() => { - - it("Should fail to create a new custom ballot with endTime before startTime", async() => { - let errorThrown = false; - try { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(5); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because endTime before startTime`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to create a new custom ballot if checkpointId does not exist", async() => { - let errorThrown = false; - try { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(15); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 10, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because checkpointId does not exist`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to create a new custom ballot if not owner", async() => { - let errorThrown = false; - try { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(15); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: account_temp }); - } catch(error) { - console.log(` tx -> failed because msg.sender is not owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully create a new custom ballot", async() => { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(15); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); - }); - }); - - describe("Cast vote", async() => { - - it("Should fail to cast a vote if token balance is zero", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor3 }); - } catch(error) { - console.log(` tx -> failed because token balance is zero`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to cast a vote if voting period has not started", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); - } catch(error) { - console.log(` tx -> failed because voting period has not started`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to cast a vote if voting period has ended", async() => { - await increaseTime(duration.minutes(20)); - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); - } catch(error) { - console.log(` tx -> failed because voting period has ended`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully cast a vote from first investor", async() => { - let tx = await I_WeightedVoteCheckpoint.castVote(false, 0, { from: account_investor1 }); - - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed to record vote"); - assert.equal(tx.logs[0].args._vote, false, "Failed to record vote"); - assert.equal(tx.logs[0].args._weight, web3.utils.toWei('1', 'ether'), "Failed to record vote"); - assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); - assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); - }); - - it("Should successfully cast a vote from second investor", async() => { - let tx = await I_WeightedVoteCheckpoint.castVote(true, 0, { from: account_investor2 }); - - assert.equal(tx.logs[0].args._investor, account_investor2, "Failed to record vote"); - assert.equal(tx.logs[0].args._vote, true, "Failed to record vote"); - assert.equal(tx.logs[0].args._weight, web3.utils.toWei('2', 'ether'), "Failed to record vote"); - assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); - assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); - }); - - it("Should fail to cast a vote again", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(false,0, { from: account_investor1 }); - } catch(error) { - console.log(` tx -> failed because holder already voted`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - }); - - describe("Get results", async() => { - - it("Should successfully get the results", async() => { - let tx = await I_WeightedVoteCheckpoint.getResults(0, { from: token_owner }); - assert.equal(tx[0], web3.utils.toWei('2', 'ether'), "Failed to get results"); - assert.equal(tx[1], web3.utils.toWei('1', 'ether'), "Failed to get results"); - assert.equal(tx[2], 0, "Failed to get results"); - }); - }); -}); From 5c0c3baeacc916e631cc8c64816e28cb61b981dc Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Tue, 9 Oct 2018 16:01:13 +0200 Subject: [PATCH 113/142] update test file name --- test/{weighted_vote_oct.js => x_weighted_vote_checkpoint.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{weighted_vote_oct.js => x_weighted_vote_checkpoint.js} (100%) diff --git a/test/weighted_vote_oct.js b/test/x_weighted_vote_checkpoint.js similarity index 100% rename from test/weighted_vote_oct.js rename to test/x_weighted_vote_checkpoint.js From c6d448edf44a84b399cbac4300968f7e6a6aa3aa Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Tue, 9 Oct 2018 21:32:44 +0530 Subject: [PATCH 114/142] Travis fix (#321) * travis changes * Update .solcover.js * Update .travis.yml * Update .travis.yml * Update .solcover.js * Testing solcover * Temp removed new modules * Restore solcover config * Restore VRTM * Shorter contract name * Removed STVRM factory * Removed events * Stripped STVRM * Restore travis config * Partial restore of STVRM * Updated solidity coverage * Strip STVRM * More stripping * more commenting * Testing something * Testing * Testing * updated travis config * Testing * Testing * Added VRTM back * Ignore STVRM in coverage * increased node memory limit * Ignore STVRM completely in coverage * Clean up * Added docs back * Removed docs * Testing shorter names again * Revert "Testing shorter names again" This reverts commit 4d42b551c6327ad2a1ef59b3e1fa7abdb8b13ff9. --- .gitignore | 1 + .solcover.js | 4 ++-- .travis.yml | 3 +-- .../SingleTradeVolumeRestrictionManager.sol | 2 +- package.json | 2 +- scripts/test.sh | 9 +++++++++ 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index fb4573022..2109c105f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ bridge.log scTopics coverageEnv /flat +/tempPoly .eslintrc.js \ No newline at end of file diff --git a/.solcover.js b/.solcover.js index 32cb416b2..65c10cd0f 100644 --- a/.solcover.js +++ b/.solcover.js @@ -4,5 +4,5 @@ module.exports = { copyPackages: ['openzeppelin-solidity'], testCommand: 'node ../node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` --network coverage', deepSkip: true, - skipFiles: ['external', 'flat'] -}; + skipFiles: ['external', 'flat', 'helpers'] +}; \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index ca293679d..ef6406947 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,6 @@ before_script: - truffle version script: - npm run test - - npm run docs notifications: slack: - secure: W4FZSabLrzF74f317hutolEHnlq2GBlQxU6b85L5XymrjgLEhlgE16c5Qz7Emoyt6le6PXL+sfG2ujJc3XYys/6hppgrHSAasuJnKCdQNpmMZ9BNyMs6WGkmB3enIf3K/FLXb26AQdwpQdIXuOeJUTf879u+YoiZV0eZH8d3+fsIOyovq9N6X5pKOpDM9iT8gGB4t7fie7xf51s+iUaHxyO9G7jDginZ4rBXHcU7mxCub9z+Z1H8+kCTnPWaF+KKVEXx4Z0nI3+urboD7E4OIP02LwrThQls2CppA3X0EoesTcdvj/HLErY/JvsXIFiFEEHZzB1Wi+k2TiOeLcYwEuHIVij+HPxxlJNX/j8uy01Uk8s4rd+0EhvfdKHJqUKqxH4YN2npcKfHEss7bU3y7dUinXQfYShW5ZewHdvc7pnnxBTfhvmdi64HdNrXAPq+s1rhciH7MmnU+tsm4lhrpr+FBuHzUMA9fOCr7b0SQytZEgWpiUls88gdbh3yG8TjyZxmZJGx09cwEP0q7VoH0UwFh7mIu5XmYdd5tWUhavTiO7YV8cUPn7MvwMsTltB3YBpF/fB26L7ka8zBhCsjm9prW6SVYU/dyO3m91VeZtO/zJFHRDA6Q58JGVW2rgzO39z193qC1EGRXqTie96VwAAtNg8+hRb+bI/CWDVzSPc= \ No newline at end of file + secure: W4FZSabLrzF74f317hutolEHnlq2GBlQxU6b85L5XymrjgLEhlgE16c5Qz7Emoyt6le6PXL+sfG2ujJc3XYys/6hppgrHSAasuJnKCdQNpmMZ9BNyMs6WGkmB3enIf3K/FLXb26AQdwpQdIXuOeJUTf879u+YoiZV0eZH8d3+fsIOyovq9N6X5pKOpDM9iT8gGB4t7fie7xf51s+iUaHxyO9G7jDginZ4rBXHcU7mxCub9z+Z1H8+kCTnPWaF+KKVEXx4Z0nI3+urboD7E4OIP02LwrThQls2CppA3X0EoesTcdvj/HLErY/JvsXIFiFEEHZzB1Wi+k2TiOeLcYwEuHIVij+HPxxlJNX/j8uy01Uk8s4rd+0EhvfdKHJqUKqxH4YN2npcKfHEss7bU3y7dUinXQfYShW5ZewHdvc7pnnxBTfhvmdi64HdNrXAPq+s1rhciH7MmnU+tsm4lhrpr+FBuHzUMA9fOCr7b0SQytZEgWpiUls88gdbh3yG8TjyZxmZJGx09cwEP0q7VoH0UwFh7mIu5XmYdd5tWUhavTiO7YV8cUPn7MvwMsTltB3YBpF/fB26L7ka8zBhCsjm9prW6SVYU/dyO3m91VeZtO/zJFHRDA6Q58JGVW2rgzO39z193qC1EGRXqTie96VwAAtNg8+hRb+bI/CWDVzSPc= diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol index dc9f64485..04c4e8f99 100644 --- a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol @@ -310,4 +310,4 @@ contract SingleTradeVolumeRestrictionManager is ITransferManager { allPermissions[0] = ADMIN; return allPermissions; } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 42cd36fd2..9f54a356b 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "fast-csv": "^2.4.1", "ganache-cli": "^6.1.8", "sol-merger": "^0.1.2", - "solidity-coverage": "^0.5.10", + "solidity-coverage": "^0.5.11", "solidity-docgen": "^0.1.0", "solium": "^1.1.6", "truffle": "^4.1.13", diff --git a/scripts/test.sh b/scripts/test.sh index d24ce6b0f..bfbd4f842 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -94,11 +94,20 @@ else fi if ! [ -z "${TRAVIS_PULL_REQUEST+x}" ] && [ "$TRAVIS_PULL_REQUEST" != false ]; then + mkdir tempPoly + mv contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol tempPoly/SingleTradeVolumeRestrictionManager.sol + mv contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol tempPoly/SingleTradeVolumeRestrictionManagerFactory.sol + mv test/x_single_trade_volume_restriction.js tempPoly/x_single_trade_volume_restriction.js node_modules/.bin/solidity-coverage if [ "$CONTINUOUS_INTEGRATION" = true ]; then cat coverage/lcov.info | node_modules/.bin/coveralls fi + + mv tempPoly/SingleTradeVolumeRestrictionManager.sol contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol + mv tempPoly/SingleTradeVolumeRestrictionManagerFactory.sol contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol + mv tempPoly/x_single_trade_volume_restriction.js test/x_single_trade_volume_restriction.js + rm -rf tempPoly else # Do not run a_poly_oracle,js tests unless it is a cron job from travis if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then From bfe65be52b5014d6d8fab3add4a037eaec3d0ae5 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Wed, 10 Oct 2018 15:03:33 +0530 Subject: [PATCH 115/142] Solidity Coverage Fix (#328) * Updated test script * Updated travis script * Mac Compatibility * Ignored mocks and oracles in test coverage --- .solcover.js | 3 ++- .travis.yml | 1 + scripts/test.sh | 13 ++----------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.solcover.js b/.solcover.js index 65c10cd0f..f835b2835 100644 --- a/.solcover.js +++ b/.solcover.js @@ -4,5 +4,6 @@ module.exports = { copyPackages: ['openzeppelin-solidity'], testCommand: 'node ../node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` --network coverage', deepSkip: true, - skipFiles: ['external', 'flat', 'helpers'] + skipFiles: ['external', 'flat', 'helpers', 'mocks', 'oracles'], + forceParse: ['mocks', 'oracles'] }; \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index ef6406947..14c03d06b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ before_install: - sudo apt-get -y install solc before_script: - truffle version + - wget -O node_modules/solidity-coverage/lib/app.js https://raw.githubusercontent.com/maxsam4/solidity-coverage/relative-path/lib/app.js script: - npm run test notifications: diff --git a/scripts/test.sh b/scripts/test.sh index bfbd4f842..6dd3ce95a 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -94,20 +94,11 @@ else fi if ! [ -z "${TRAVIS_PULL_REQUEST+x}" ] && [ "$TRAVIS_PULL_REQUEST" != false ]; then - mkdir tempPoly - mv contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol tempPoly/SingleTradeVolumeRestrictionManager.sol - mv contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol tempPoly/SingleTradeVolumeRestrictionManagerFactory.sol - mv test/x_single_trade_volume_restriction.js tempPoly/x_single_trade_volume_restriction.js + curl -o node_modules/solidity-coverage/lib/app.js https://raw.githubusercontent.com/maxsam4/solidity-coverage/relative-path/lib/app.js node_modules/.bin/solidity-coverage - if [ "$CONTINUOUS_INTEGRATION" = true ]; then cat coverage/lcov.info | node_modules/.bin/coveralls fi - - mv tempPoly/SingleTradeVolumeRestrictionManager.sol contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol - mv tempPoly/SingleTradeVolumeRestrictionManagerFactory.sol contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol - mv tempPoly/x_single_trade_volume_restriction.js test/x_single_trade_volume_restriction.js - rm -rf tempPoly else # Do not run a_poly_oracle,js tests unless it is a cron job from travis if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then @@ -115,4 +106,4 @@ else else node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` fi -fi +fi \ No newline at end of file From 3f4f6db851ed5060dc554ca4ce1b633b7db5a873 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Wed, 10 Oct 2018 14:31:45 +0200 Subject: [PATCH 116/142] fixed pull comments --- .../Checkpoint/WeightedVoteCheckpoint.sol | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol index 6ab4d8777..2beaf0014 100644 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol @@ -33,7 +33,7 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { event BallotCreated(uint256 _startTime, uint256 _endTime, uint256 _ballotId, uint256 _checkpointId); event VoteCasted(uint256 _ballotId, uint256 _time, address indexed _investor, uint256 _weight, bool _vote); - event BallotDeactivated(uint256 _ballotId, bool _isActive); + event BallotActiveStatsChanged(uint256 _ballotId, bool _isActive); /** * @notice Constructor @@ -89,14 +89,11 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { * @param _duration The duration of the voting period in seconds * @return bool success */ - function createBallot(uint256 _duration) public onlyOwner returns (bool) { - uint256 ballotId = ballots.length; + function createBallot(uint256 _duration) public onlyOwner { + require(_duration > 0, "Incorrect ballot duration."); uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); - uint256 currentSupply = ISecurityToken(securityToken).totalSupply(); uint256 endTime = now.add(_duration); - ballots.push(Ballot(checkpointId,currentSupply,now,endTime,0,0,0,true)); - emit BallotCreated(now, endTime, ballotId, checkpointId); - return true; + createCustomBallot(now, endTime, checkpointId); } /** @@ -106,13 +103,12 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { * @param _checkpointId Index of the checkpoint to use for token balances * @return bool success */ - function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner returns (bool) { - require(_endTime >= _startTime); + function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner { + require(_endTime > _startTime); uint256 ballotId = ballots.length; uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0, true)); emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); - return true; } /** @@ -121,17 +117,14 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { * @param _isActive The bool value of the active stats of the ballot * @return bool success */ - function setActiveStatsBallot(uint256 _ballotId, bool _isActive) public onlyOwner returns (bool) { - require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); + function setActiveStatsBallot(uint256 _ballotId, bool _isActive) public onlyOwner { + require(now < ballots[_ballotId].endTime, "This ballot has already ended."); + require(ballots[_ballotId].isActive != _isActive, "Active state unchanged"); ballots[_ballotId].isActive = _isActive; - emit BallotDeactivated(_ballotId, _isActive); - return true; + emit BallotActiveStatsChanged(_ballotId, _isActive); } - // /** - // * @notice Init function i.e generalise function to maintain the structure of the module contract - // * @return bytes4 - // */ + function getInitFunction() public returns(bytes4) { return bytes4(0); } From b94c06863a4eb6f888ad77f69b2b1a06612a9d82 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Wed, 10 Oct 2018 14:47:22 +0200 Subject: [PATCH 117/142] fixed pull request comments --- contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol index 2beaf0014..70acd5a19 100644 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol +++ b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol @@ -104,7 +104,7 @@ contract WeightedVoteCheckpoint is ICheckpoint, Module { * @return bool success */ function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner { - require(_endTime > _startTime); + require(_endTime > _startTime, "Ballot end time must be later than start time."); uint256 ballotId = ballots.length; uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0, true)); From 14acb4e46e6f166f287ea0000fae4883e19d1bb9 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Wed, 10 Oct 2018 18:10:13 +0200 Subject: [PATCH 118/142] fixed permission manager test causing fail --- test/g_general_permission_manager.js | 335 +++++++++++++++------------ 1 file changed, 189 insertions(+), 146 deletions(-) diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 4a253b0cb..b04f8a18d 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -1,22 +1,32 @@ -import latestTime from "./helpers/latestTime"; -import { signData } from "./helpers/signData"; -import { pk } from "./helpers/testprivateKey"; -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; -import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; -import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; -import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed } from "./helpers/createInstances"; - -const DummySTO = artifacts.require("./DummySTO.sol"); -const SecurityToken = artifacts.require("./SecurityToken.sol"); -const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); - -const Web3 = require("web3"); -const BigNumber = require("bignumber.js"); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port - -contract("GeneralPermissionManager", accounts => { +import latestTime from './helpers/latestTime'; +import {signData} from './helpers/signData'; +import { pk } from './helpers/testprivateKey'; +import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; +import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; +import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; + +const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') +const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); +const DummySTO = artifacts.require('./DummySTO.sol'); +const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); +const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); +const SecurityToken = artifacts.require('./SecurityToken.sol'); +const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); +const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); +const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); +const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); + +const Web3 = require('web3'); +const BigNumber = require('bignumber.js'); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract('GeneralPermissionManager', accounts => { + // Accounts Variable declaration let account_polymath; let account_issuer; @@ -74,15 +84,17 @@ contract("GeneralPermissionManager", accounts => { const initRegFee = web3.utils.toWei("250"); // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei("10", "ether"); + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei('10', 'ether'); const someString = "A string which is not used"; - const STOParameters = ["uint256", "uint256", "uint256", "string"]; + const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; + const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; + const MRProxyParameters = ['address', 'address']; let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); - before(async () => { + before(async() => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -96,43 +108,61 @@ contract("GeneralPermissionManager", accounts => { account_delegate2 = accounts[6]; account_delegate3 = accounts[5]; - // Step 1: Deploy the genral PM ecosystem - let instances = await setUpPolymathNetwork(account_polymath, token_owner); - - [ - I_PolymathRegistry, - I_PolyToken, - I_FeatureRegistry, - I_ModuleRegistry, - I_ModuleRegistryProxy, - I_MRProxied, - I_GeneralTransferManagerFactory, - I_STFactory, - I_SecurityTokenRegistry, - I_SecurityTokenRegistryProxy, - I_STRProxied - ] = instances; - + // ----------- POLYMATH NETWORK Configuration ------------ + + // Step 0: Deploy the PolymathRegistry + I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); + + // Step 1: Deploy the token Faucet and Mint tokens for token_owner + I_PolyToken = await PolyTokenFaucet.new(); + await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); + + // Step 2: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + + // STEP 3: Deploy the ModuleRegistry + + I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); + // Step 3 (b): Deploy the proxy and attach the implementation contract to it + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); + let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + + // STEP 4: Deploy the GeneralTransferManagerFactory + + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); + + assert.notEqual( + I_GeneralTransferManagerFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "GeneralTransferManagerFactory contract was not deployed" + ); - // STEP 5: Deploy the GeneralPermissionManagerFactory + // STEP 5: Deploy the GeneralDelegateManagerFactory I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); assert.notEqual( I_GeneralPermissionManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "GeneralPermissionManagerFactory contract was not deployed" + "GeneralDelegateManagerFactory contract was not deployed" ); - // STEP 6: Deploy the GeneralPermissionManagerFactory + // STEP 6: Deploy the GeneralDelegateManagerFactory P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); assert.notEqual( P_GeneralPermissionManagerFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", - "GeneralPermissionManagerFactory contract was not deployed" + "GeneralDelegateManagerFactory contract was not deployed" ); // STEP 7: Deploy the DummySTOFactory @@ -185,11 +215,11 @@ contract("GeneralPermissionManager", accounts => { await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the GeneralPermissionManagerFactory + // (B) : Register the GeneralDelegateManagerFactory await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - // (B) : Register the Paid GeneralPermissionManagerFactory + // (B) : Register the Paid GeneralDelegateManagerFactory await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); @@ -200,26 +230,27 @@ contract("GeneralPermissionManager", accounts => { // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistryProxy ${I_ModuleRegistryProxy.address} - ModuleRegistry: ${I_ModuleRegistry.address} - FeatureRegistry: ${I_FeatureRegistry.address} + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistryProxy ${ModuleRegistryProxy.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} DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); }); - describe("Generate the SecurityToken", async () => { + describe("Generate the SecurityToken", async() => { + it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -227,47 +258,50 @@ contract("GeneralPermissionManager", accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); + assert.equal( + web3.utils.toAscii(log.args._name) + .replace(/\u0000/g, ''), + "GeneralTransferManager" + ); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the General permission manager factory with the security token", async () => { + let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - await catchRevert( - I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { - from: token_owner - }) - ); + try { + const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + } catch(error) { + console.log(` tx -> failed because Token is not paid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); }); it("Should successfully attach the General permission manager factory with the security token", async () => { let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); - const tx = await I_SecurityToken.addModule( - P_GeneralPermissionManagerFactory.address, - "0x", - web3.utils.toWei("500", "ether"), - 0, - { from: token_owner } - ); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); + const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), + web3.utils.toAscii(tx.logs[3].args._name) + .replace(/\u0000/g, ''), "GeneralPermissionManager", "GeneralPermissionManagerFactory module was not added" ); @@ -279,7 +313,8 @@ contract("GeneralPermissionManager", accounts => { const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), + web3.utils.toAscii(tx.logs[2].args._name) + .replace(/\u0000/g, ''), "GeneralPermissionManager", "GeneralPermissionManagerFactory module was not added" ); @@ -288,34 +323,47 @@ contract("GeneralPermissionManager", accounts => { }); - describe("General Permission Manager test cases", async () => { - it("Get the init data", async () => { - let tx = await I_GeneralPermissionManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ""), 0); - }); - - it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async () => { - await catchRevert(I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1 })); - }); + describe("General Permission Manager test cases", async() => { - it("Should fail to provide the permission-- because delegate is not yet added", async () => { - await catchRevert( - I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { - from: token_owner - }) - ); + it("Get the init data", async() => { + let tx = await I_GeneralPermissionManager.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); }); it("Should fail in adding the delegate -- msg.sender doesn't have permission", async() => { - await catchRevert( - I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}) - ); + let errorThrown = false; + try { + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}); + } catch(error) { + console.log(` tx revert -> msg.sender doesn't have permission`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); }); it("Should fail in adding the delegate -- no delegate details provided", async() => { - await catchRevert( - I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: account_investor1}) - ); + let errorThrown = false; + try { + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: account_investor1}); + } catch(error) { + console.log(` tx revert -> delegate details were not provided`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should fail to provide the permission -- because delegate is not yet added", async() => { + let errorThrown = false; + try { + let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); + } catch(error) { + console.log(` tx revert -> Delegate is not yet added`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); }); it("Should successfuly add the delegate", async() => { @@ -323,35 +371,29 @@ contract("GeneralPermissionManager", accounts => { assert.equal(tx.logs[0].args._delegate, account_delegate); }); - it("Should fail to provide the permission", async () => { - await catchRevert( - I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { - from: account_investor1 - }) - ); + it("Should fail to provide the permission", async() => { + let errorThrown = false; + try { + let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1}); + } catch(error) { + console.log(` tx revert -> msg.sender doesn't have permission`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); }); - it("Should check the permission", async () => { - assert.isFalse( - await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST") - ); + it("Should check the permission", async() => { + assert.isFalse(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); }); - it("Should provide the permission", async () => { - let tx = await I_GeneralPermissionManager.changePermission( - account_delegate, - I_GeneralTransferManager.address, - "WHITELIST", - true, - { from: token_owner } - ); + it("Should provide the permission", async() => { + let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate); }); - it("Should check the permission", async () => { - assert.isTrue( - await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST") - ); + it("Should check the permission", async() => { + assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); }); it("Should check the delegate details", async() => { @@ -361,9 +403,12 @@ contract("GeneralPermissionManager", accounts => { "Wrong delegate address get checked"); }); - it("Should get the permission of the general permission manager contract", async () => { + it("Should get the permission of the general permission manager contract", async() => { let tx = await I_GeneralPermissionManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ""), "CHANGE_PERMISSION", "Wrong permissions"); + assert.equal(web3.utils.toAscii(tx[0]) + .replace(/\u0000/g, ''), + "CHANGE_PERMISSION", + "Wrong permissions"); }); it("Should return all delegates", async() => { @@ -419,32 +464,30 @@ contract("GeneralPermissionManager", accounts => { }); - describe("General Permission Manager Factory test cases", async () => { - it("should get the exact details of the factory", async () => { - assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(), 0); - assert.equal((await I_GeneralPermissionManagerFactory.getTypes.call())[0], 1); - assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), "1.0.0"); - assert.equal( - web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()).replace(/\u0000/g, ""), - "GeneralPermissionManager", - "Wrong Module added" - ); - assert.equal( - await I_GeneralPermissionManagerFactory.getDescription.call(), - "Manage permissions within the Security Token and attached modules", - "Wrong Module added" - ); - assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), "General Permission Manager", "Wrong Module added"); - assert.equal( - await I_GeneralPermissionManagerFactory.getInstructions.call(), - "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", - "Wrong Module added" - ); + describe("General Permission Manager Factory test cases", async() => { + it("should get the exact details of the factory", async() => { + assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); + assert.equal((await I_GeneralPermissionManagerFactory.getTypes.call())[0],1); + assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) + .replace(/\u0000/g, ''), + "GeneralPermissionManager", + "Wrong Module added"); + assert.equal(await I_GeneralPermissionManagerFactory.getDescription.call(), + "Manage permissions within the Security Token and attached modules", + "Wrong Module added"); + assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), + "General Permission Manager", + "Wrong Module added"); + assert.equal(await I_GeneralPermissionManagerFactory.getInstructions.call(), + "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", + "Wrong Module added"); + }); - it("Should get the tags of the factory", async () => { + it("Should get the tags of the factory", async() => { let tags = await I_GeneralPermissionManagerFactory.getTags.call(); - assert.equal(tags.length, 0); + assert.equal(tags.length,0); }); }); + }); From 9dc1fc91134489a3eea203aa98ba0f276861116a Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Wed, 10 Oct 2018 20:33:22 -0300 Subject: [PATCH 119/142] Migration script to 2.0.0 (#325) * CLI: data bytes for verifyTransfer * Migration script for tickers and tokens from 1.4.0 * Minor fixes * added missing package and modified data files * Tickers and ST migration instructions * Possibility to migrate a singe ticker/token * Update whitelist_data.csv --- CLI/commands/ST20Generator.js | 2 +- CLI/commands/multi_mint.js | 6 +- CLI/commands/strMigrator.js | 361 +- CLI/data/GeneralTransferManager1-4-0.json | 18784 +++++++ CLI/data/SecurityToken1-4-0.json | 53469 ++++++++++++++++++++ CLI/data/accredited_data.csv | 20 +- CLI/data/dividendsExclusions_data.csv | 10 +- CLI/data/multi_mint_data.csv | 20 +- CLI/data/nonAccreditedLimits_data.csv | 17 +- CLI/data/whitelist_data.csv | 21 +- CLI/package-lock.json | 47 +- CLI/package.json | 2 + CLI/polymath-cli.js | 6 +- UPGRADE-PROCEDURES.md | 14 + package.json | 1 + yarn.lock | 41 +- 16 files changed, 72688 insertions(+), 133 deletions(-) create mode 100644 CLI/data/GeneralTransferManager1-4-0.json create mode 100644 CLI/data/SecurityToken1-4-0.json diff --git a/CLI/commands/ST20Generator.js b/CLI/commands/ST20Generator.js index 1b7fd034b..d6ca10a32 100644 --- a/CLI/commands/ST20Generator.js +++ b/CLI/commands/ST20Generator.js @@ -997,7 +997,7 @@ async function usdTieredSTO_configure() { switch (index) { case 0: let reserveWallet = await currentSTO.methods.reserveWallet().call(); - let isVerified = await generalTransferManager.methods.verifyTransfer(STO_Address, reserveWallet, 0, false).call(); + let isVerified = await generalTransferManager.methods.verifyTransfer(STO_Address, reserveWallet, 0, web3.utils.fromAscii("")).call(); if (isVerified == "2") { if (readlineSync.keyInYNStrict()) { let finalizeAction = currentSTO.methods.finalize(); diff --git a/CLI/commands/multi_mint.js b/CLI/commands/multi_mint.js index 908216b58..736981789 100644 --- a/CLI/commands/multi_mint.js +++ b/CLI/commands/multi_mint.js @@ -142,7 +142,7 @@ function readFile() { for (let j = 0; j < distribData[i].length; j++) { let investorAccount = distribData[i][j][0]; let tokenAmount = web3.utils.toWei((distribData[i][j][1]).toString(),"ether"); - let verifiedTransaction = await securityToken.methods.verifyTransfer("0x0000000000000000000000000000000000000000", investorAccount, tokenAmount).call(); + let verifiedTransaction = await securityToken.methods.verifyTransfer("0x0000000000000000000000000000000000000000", investorAccount, tokenAmount, web3.utils.fromAscii("")).call(); if (verifiedTransaction) { affiliatesVerifiedArray.push(investorAccount); tokensVerifiedArray.push(tokenAmount); @@ -181,8 +181,8 @@ function readFile() { for (var i = 0; i < event_data.length; i++) { let combineArray = []; - let investorAddress_Event = event_data[i].returnValues.to; - let amount_Event = event_data[i].returnValues.amount; + let investorAddress_Event = event_data[i].returnValues._to; + let amount_Event = event_data[i].returnValues._value; let blockNumber = event_data[i].blockNumber combineArray.push(investorAddress_Event); diff --git a/CLI/commands/strMigrator.js b/CLI/commands/strMigrator.js index a2ba4bdf0..545455f46 100644 --- a/CLI/commands/strMigrator.js +++ b/CLI/commands/strMigrator.js @@ -1,10 +1,15 @@ var readlineSync = require('readline-sync'); var chalk = require('chalk'); +var request = require('request-promise') var abis = require('./helpers/contract_abis'); +var contracts = require('./helpers/contract_addresses'); var common = require('./common/common_functions'); var global = require('./common/global'); -async function executeApp(fromStrAddress, toStrAddress, remoteNetwork) { +let network; + +async function executeApp(toStrAddress, fromTrAddress, fromStrAddress, remoteNetwork) { + network = remoteNetwork; await global.initialize(remoteNetwork); common.logAsciiBull(); @@ -15,27 +20,30 @@ async function executeApp(fromStrAddress, toStrAddress, remoteNetwork) { console.log("Issuer Account: " + Issuer.address + "\n"); try { - let fromSTR = step_instance_fromSTR(fromStrAddress); - let toSTR = step_instance_toSTR(toStrAddress); - let tokens = await step_get_deployed_tokens(fromSTR); - await step_add_Custom_STs(tokens, toSTR); + let toSecurityTokenRegistry = await step_instance_toSTR(toStrAddress); + let fromTickerRegistry = await step_instance_fromTR(fromTrAddress); + let tickers = await step_get_registered_tickers(fromTickerRegistry); + await step_register_tickers(tickers, toSecurityTokenRegistry); + let fromSecurityTokenRegistry = await step_instance_fromSTR(fromStrAddress); + let tokens = await step_get_deployed_tokens(fromSecurityTokenRegistry); + await step_launch_STs(tokens, toSecurityTokenRegistry); } catch (err) { console.log(err); return; } } -function step_instance_fromSTR(fromStrAddress){ - let _fromStrAddress; - if (typeof fromStrAddress !== 'undefined') { - if (web3.utils.isAddress(fromStrAddress)) { - _fromStrAddress = fromStrAddress; +async function step_instance_toSTR(toStrAddress){ + let _toStrAddress; + if (typeof toStrAddress !== 'undefined') { + if (web3.utils.isAddress(toStrAddress)) { + _toStrAddress = toStrAddress; } else { - console.log(chalk.red("Entered fromStrAddress is not a valid address.")); + console.log(chalk.red("Entered toStrAddress is not a valid address.")); return; } } else { - _fromStrAddress = readlineSync.question('Enter the old SecurityTokenRegistry address to migrate FROM: ', { + _toStrAddress = readlineSync.question('Enter the new SecurityTokenRegistry address to migrate TO: ', { limit: function(input) { return web3.utils.isAddress(input); }, @@ -43,25 +51,25 @@ function step_instance_fromSTR(fromStrAddress){ }); } - console.log(`Creating SecurityTokenRegistry contract instance of address: ${_fromStrAddress}...`); + console.log(`Creating SecurityTokenRegistry contract instance of address: ${_toStrAddress}...`); let securityTokenRegistryABI = abis.securityTokenRegistry(); - let fromSTR = new web3.eth.Contract(securityTokenRegistryABI, _fromStrAddress); - fromSTR.setProvider(web3.currentProvider); + let toSTR = new web3.eth.Contract(securityTokenRegistryABI, _toStrAddress); + toSTR.setProvider(web3.currentProvider); - return fromSTR; + return toSTR; } -function step_instance_toSTR(toStrAddress){ - let _toStrAddress; - if (typeof toStrAddress !== 'undefined') { - if (web3.utils.isAddress(toStrAddress)) { - _toStrAddress = toStrAddress; +async function step_instance_fromTR(fromTrAddress){ + let _fromTrAddress; + if (typeof fromTrAddress !== 'undefined') { + if (web3.utils.isAddress(fromTrAddress)) { + _fromTrAddress = fromTrAddress; } else { - console.log(chalk.red("Entered toStrAddress is not a valid address.")); + console.log(chalk.red("Entered fromTrAddress is not a valid address.")); return; } } else { - _toStrAddress = readlineSync.question('Enter the new SecurityTokenRegistry address to migrate TO: ', { + _fromTrAddress = readlineSync.question('Enter the old TikcerRegistry address to migrate FROM: ', { limit: function(input) { return web3.utils.isAddress(input); }, @@ -69,90 +77,307 @@ function step_instance_toSTR(toStrAddress){ }); } - console.log(`Creating SecurityTokenRegistry contract instance of address: ${_toStrAddress}...`); - let securityTokenRegistryABI = abis.securityTokenRegistry(); - let toSTR = new web3.eth.Contract(securityTokenRegistryABI, _toStrAddress); - toSTR.setProvider(web3.currentProvider); + console.log(`Creating TickerRegistry contract instance of address: ${_fromTrAddress}...`); + let tickerRegistryABI = await getABIfromEtherscan(_fromTrAddress); + let fromTR = new web3.eth.Contract(tickerRegistryABI, _fromTrAddress); + fromTR.setProvider(web3.currentProvider); - return toSTR; + return fromTR; } -async function step_get_deployed_tokens(securityTokenRegistry) { - let tokens = []; - - let events = await securityTokenRegistry.getPastEvents('NewSecurityToken', { fromBlock: 0}); +async function step_get_registered_tickers(tickerRegistry) { + let tickers = []; + let expiryTime = await tickerRegistry.methods.expiryLimit().call(); + + let events = await tickerRegistry.getPastEvents('LogRegisterTicker', { fromBlock: 0}); if (events.length == 0) { - console.log("No security token events were emitted."); + console.log("No ticker registration events were emitted."); } else { for (let event of events) { - console.log(`-------- LogNewSecurityToken event --------`); - console.log(`Ticker: ${event.returnValues._ticker}`); - console.log(`Token address: ${event.returnValues._securityTokenAddress}`); + //for (let index = 0; index < 2; index++) { + //const event = events[index]; + let details = await tickerRegistry.methods.getDetails(event.returnValues._symbol).call(); + let _symbol = event.returnValues._symbol; + let _owner = details[0]; + let _name = details[2]; + let _registrationDate = details[1]; + let _status = details[4]; + + console.log(`------------ Ticker Registered ------------`); + console.log(`Ticker: ${_symbol}`); + console.log(`Owner: ${_owner}`); + console.log(`Token name: ${_name}`); + console.log(`Timestamp: ${_registrationDate}`); console.log(`Transaction hash: ${event.transactionHash}`); console.log(`-------------------------------------------`); console.log(`\n`); + + tickers.push({ + ticker: _symbol, + owner: _owner, + name: _name, + registrationDate: new web3.utils.BN(_registrationDate), + expiryDate: new web3.utils.BN(_registrationDate).add(new web3.utils.BN(expiryTime)), + status: _status + }); + } + } + + console.log(chalk.yellow(`${tickers.length} tickers found!`)); + return tickers; +} + +async function step_register_tickers(tickers, securityTokenRegistry) { + if (readlineSync.keyInYNStrict(`Do you want to migrate a single Ticker?`)) { + let tickerToMigrate = readlineSync.question(`Enter the ticker to migrate: `); + tickers = tickers.filter(t => t.ticker == tickerToMigrate); + } + + if (tickers.length == 0) { + console.log(chalk.yellow(`There are no tickers to migrate!`)); + } else if (readlineSync.keyInYNStrict(`Do you want to migrate ${tickers.length} Tickers?`)) { + let i = 0; + let succeed = []; + let failed = []; + let totalGas = new web3.utils.BN(0); + for (const t of tickers) { + console.log(`\n`); + console.log(`-------- Migrating ticker No ${++i}--------`); + console.log(`Ticker: ${t.ticker}`); + console.log(``); + try { + let modifyTickerAction = securityTokenRegistry.methods.modifyTicker(t.owner, t.ticker, t.name, t.registrationDate, t.expiryDate, false); + let receipt = await common.sendTransaction(Issuer, modifyTickerAction, defaultGasPrice); + totalGas = totalGas.add(new web3.utils.BN(receipt.gasUsed)); + succeed.push(t); + } catch (error) { + failed.push(t); + console.log(chalk.red(`Transaction failed!!! `)) + console.log(error); + } + } + + logTickerResults(succeed, failed, totalGas); + } +} + +async function step_instance_fromSTR(fromStrAddress){ + let _fromStrAddress; + if (typeof fromStrAddress !== 'undefined') { + if (web3.utils.isAddress(fromStrAddress)) { + _fromStrAddress = fromStrAddress; + } else { + console.log(chalk.red("Entered fromStrAddress is not a valid address.")); + return; + } + } else { + _fromStrAddress = readlineSync.question('Enter the old SecurityTokenRegistry address to migrate FROM: ', { + limit: function(input) { + return web3.utils.isAddress(input); + }, + limitMessage: "Must be a valid address" + }); + } + console.log(`Creating SecurityTokenRegistry contract instance of address: ${_fromStrAddress}...`); + let securityTokenRegistryABI = await getABIfromEtherscan(_fromStrAddress); + let fromSTR = new web3.eth.Contract(securityTokenRegistryABI, _fromStrAddress); + fromSTR.setProvider(web3.currentProvider); + + return fromSTR; +} + +async function step_get_deployed_tokens(securityTokenRegistry) { + let tokens = []; + + let events = await securityTokenRegistry.getPastEvents('LogNewSecurityToken', { fromBlock: 0}); + if (events.length == 0) { + console.log("No security token events were emitted."); + } else { + for (let event of events) { + //for (let index = 0; index < 2; index++) { + //const event = events[index]; let tokenAddress = event.returnValues._securityTokenAddress; - let securityTokenABI = abis.securityToken(); + let securityTokenABI = JSON.parse(require('fs').readFileSync('./CLI/data/SecurityToken1-4-0.json').toString()).abi; console.log(`Creating SecurityToken contract instance of address: ${tokenAddress}...`); let token = new web3.eth.Contract(securityTokenABI, tokenAddress); token.setProvider(web3.currentProvider); let tokenName = await token.methods.name().call(); let tokenSymbol = await token.methods.symbol().call(); - let tokenOwner = event.returnValues._owner;//await token.methods.owner().call(); + let tokenOwner = await token.methods.owner().call(); let tokenDetails = await token.methods.tokenDetails().call(); - - tokens.push({ name: tokenName, symbol: tokenSymbol, owner: tokenOwner, details: tokenDetails, address: tokenAddress }); + let tokenDivisible = await token.methods.granularity().call() == 1; + let tokenDeployedAt = (await web3.eth.getBlock(event.blockNumber)).timestamp; + + let gmtAddress = (await token.methods.getModule(2, 0).call())[1]; + let gtmABI = JSON.parse(require('fs').readFileSync('./CLI/data/GeneralTransferManager1-4-0.json').toString()).abi; + let gmt = new web3.eth.Contract(gtmABI, gmtAddress); + let gtmEvents = await gmt.getPastEvents('LogModifyWhitelist', { fromBlock: event.blockNumber}); + + let mintedEvents = []; + if (gtmEvents.length > 0) { + mintedEvents = await token.getPastEvents('Minted', { fromBlock: event.blockNumber}); + } + + console.log(`--------- SecurityToken launched ---------`); + console.log(`Token address: ${event.returnValues._securityTokenAddress}`); + console.log(`Symbol: ${tokenSymbol}`); + console.log(`Name: ${tokenName}`); + console.log(`Owner: ${tokenOwner}`); + console.log(`Details: ${tokenDetails}`); + console.log(`Divisble: ${tokenDivisible}`); + console.log(`Deployed at: ${tokenDeployedAt}`); + console.log(`Transaction hash: ${event.transactionHash}`); + console.log(`------------------------------------------`); + console.log(``); + + + tokens.push({ + name: tokenName, + ticker: tokenSymbol, + owner: tokenOwner, + details: tokenDetails, + address: tokenAddress, + deployedAt: tokenDeployedAt, + divisble: tokenDivisible, + gmtEvents: gtmEvents, + mintedEvents: mintedEvents + }); } } - console.log(chalk.yellow(`${tokens.length} found and they are going to be migrated!`)); + console.log(chalk.yellow(`${tokens.length} security tokens found!`)); return tokens; } -async function step_add_Custom_STs(tokens, toStr) { - let i = 0; - let succeed = []; - let failed = []; - let totalGas = new web3.utils.BN(0); - for (const t of tokens) { - console.log(`\n`); - console.log(`-------- Migrating token No ${++i}--------`); - console.log(`Token symbol: ${t.symbol}`); - console.log(`Token address: ${t.address}`); - console.log(`\n`); - try { - let addCustomSTAction = toStr.methods.addCustomSecurityToken(t.name, t.symbol, t.owner, t.address, t.details); - let receipt = await common.sendTransaction(Issuer, addCustomSTAction, defaultGasPrice); - totalGas = totalGas.add(new web3.utils.BN(receipt.gasUsed)); - succeed.push(t); - } catch (error) { - failed.push(t); - console.log(chalk.red(`Transaction failed!!! `)) - console.log(error); +async function step_launch_STs(tokens, securityTokenRegistry) { + if (readlineSync.keyInYNStrict(`Do you want to migrate a single Security Token?`)) { + let tokenToMigrate = readlineSync.question(`Enter the Security Token symbol to migrate: `); + tokens = tokens.filter(t => t.ticker == tokenToMigrate); + } + + if (tickers.length == 0) { + console.log(chalk.yellow(`There are no security tokens to migrate!`)); + } else if (readlineSync.keyInYNStrict(`Do you want to migrate ${tokens.length} Security Tokens?`)) { + let i = 0; + let succeed = []; + let failed = []; + let totalGas = new web3.utils.BN(0); + let polymathRegistryAddress = await contracts.polymathRegistry(); + let STFactoryABI = JSON.parse(require('fs').readFileSync('./build/contracts/STFactory.json').toString()).abi; + let STFactoryAddress = await securityTokenRegistry.methods.getSTFactoryAddress().call(); + let STFactory = new web3.eth.Contract(STFactoryABI, STFactoryAddress); + for (const t of tokens) { + console.log(`\n`); + console.log(`-------- Migrating token No ${++i}--------`); + console.log(`Token symbol: ${t.ticker}`); + console.log(`Token address: ${t.address}`); + console.log(``); + try { + // Deploying 2.0.0 Token + let deployTokenAction = STFactory.methods.deployToken(t.name, t.ticker, 18, t.details, Issuer.address, t.divisble, polymathRegistryAddress) + let deployTokenReceipt = await common.sendTransaction(Issuer, deployTokenAction, defaultGasPrice); + // Instancing Security Token + let newTokenAddress = deployTokenReceipt.logs[deployTokenReceipt.logs.length -1].address; //Last log is the ST creation + let newTokenABI = abis.securityToken(); + let newToken = new web3.eth.Contract(newTokenABI, newTokenAddress); + + // Checking if the old Security Token has activity + if (t.gmtEvents.length > 0) { + // Instancing GeneralTransferManager + let gmtABI = abis.generalTransferManager(); + let gmtAddress = (await newToken.methods.getModulesByName(web3.utils.toHex("GeneralTransferManager")).call())[0]; + let gmt = new web3.eth.Contract(gmtABI, gmtAddress); + // Whitelisting investors + for (const gmtEvent of t.gmtEvents) { + let modifyWhitelistAction = gmt.methods.modifyWhitelist( + gmtEvent.returnValues._investor, + new web3.utils.BN(gmtEvent.returnValues._fromTime), + new web3.utils.BN(gmtEvent.returnValues._toTime), + new web3.utils.BN(gmtEvent.returnValues._expiryTime), + gmtEvent.returnValues._canBuyFromSTO + ); + let modifyWhitelistReceipt = await common.sendTransaction(Issuer, modifyWhitelistAction, defaultGasPrice); + totalGas = totalGas.add(new web3.utils.BN(modifyWhitelistReceipt.gasUsed)); + } + // Minting tokens + for (const mintedEvent of t.mintedEvents) { + let mintAction = newToken.methods.mint(mintedEvent.returnValues.to, new web3.utils.BN(mintedEvent.returnValues.value)); + let mintReceipt = await common.sendTransaction(Issuer, mintAction, defaultGasPrice); + totalGas = totalGas.add(new web3.utils.BN(mintReceipt.gasUsed)); + } + } + + // Transferring onweship to the original owner + let transferOwnershipAction = newToken.methods.transferOwnership(t.owner); + let transferOwnershipReceipt = await common.sendTransaction(Issuer, transferOwnershipAction, defaultGasPrice); + totalGas = totalGas.add(new web3.utils.BN(transferOwnershipReceipt.gasUsed)); + + // Adding 2.0.0 Security Token to SecurityTokenRegistry + let modifySecurityTokenAction = securityTokenRegistry.methods.modifySecurityToken(t.name, t.ticker, t.owner, newTokenAddress, t.details, t.deployedAt); + let modifySecurityTokenReceipt = await common.sendTransaction(Issuer, modifySecurityTokenAction, defaultGasPrice); + totalGas = totalGas.add(new web3.utils.BN(modifySecurityTokenReceipt.gasUsed)); + + succeed.push(t); + } catch (error) { + failed.push(t); + console.log(chalk.red(`Transaction failed!!! `)) + console.log(error); + } } - } - logResults(succeed, failed, totalGas); + logTokenResults(succeed, failed, totalGas); + } } -function logResults(succeed, failed, totalGas) { +function logTokenResults(succeed, failed, totalGas) { console.log(` -------------------------------------------- ------------ Migration Results ----------- +--------- Token Migration Results ---------- -------------------------------------------- Successful migrations: ${succeed.length} Failed migrations: ${failed.length} Total gas consumed: ${totalGas} -Total gas cost: ${web3.utils.fromWei(defaultGasPrice.mul(totalGas))} ETH +Total gas cost: ${web3.utils.fromWei((new web3.utils.BN(defaultGasPrice)).mul(totalGas))} ETH List of failed registrations: ${failed.map(token => chalk.red(`${token.symbol} at ${token.address}`)).join('\n')} `); } +function logTickerResults(succeed, failed, totalGas) { + console.log(` +-------------------------------------------- +--------- Ticker Migration Results --------- +-------------------------------------------- +Successful migrations: ${succeed.length} +Failed migrations: ${failed.length} +Total gas consumed: ${totalGas} +Total gas cost: ${web3.utils.fromWei((new web3.utils.BN(defaultGasPrice)).mul(totalGas))} ETH +List of failed registrations: +${failed.map(ticker => chalk.red(`${ticker.ticker}`)).join('\n')} +`); +} + +async function getABIfromEtherscan(_address) { + let urlDomain = network == 'kovan' ? 'api-kovan' : 'api'; + const options = { + url: `https://${urlDomain}.etherscan.io/api`, + qs: { + module: 'contract', + action: 'getabi', + address: _address, + apikey: 'THM9IUVC2DJJ6J5MTICDE6H1HGQK14X559' + }, + method: 'GET', + json: true + }; + let data = await request(options); + return JSON.parse(data.result); +} + module.exports = { - executeApp: async function(fromStrAddress, toStrAddress, remoteNetwork) { - return executeApp(fromStrAddress, toStrAddress, remoteNetwork); + executeApp: async function(toStrAddress, fromTrAddress, fromStrAddress, remoteNetwork) { + return executeApp(toStrAddress, fromTrAddress, fromStrAddress, remoteNetwork); } }; \ No newline at end of file diff --git a/CLI/data/GeneralTransferManager1-4-0.json b/CLI/data/GeneralTransferManager1-4-0.json new file mode 100644 index 000000000..1d27189ba --- /dev/null +++ b/CLI/data/GeneralTransferManager1-4-0.json @@ -0,0 +1,18784 @@ +{ + "contractName": "GeneralTransferManager", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "allowAllBurnTransfers", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "WHITELIST", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "allowAllWhitelistTransfers", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "unpause", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "paused", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_amount", + "type": "uint256" + } + ], + "name": "takeFee", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "polyToken", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "pause", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "FLAGS", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "whitelist", + "outputs": [ + { + "name": "fromTime", + "type": "uint256" + }, + { + "name": "toTime", + "type": "uint256" + }, + { + "name": "expiryTime", + "type": "uint256" + }, + { + "name": "canBuyFromSTO", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "allowAllTransfers", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "signingAddress", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "issuanceAddress", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "securityToken", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "factory", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "FEE_ADMIN", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "allowAllWhitelistIssuances", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_securityToken", + "type": "address" + }, + { + "name": "_polyAddress", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_issuanceAddress", + "type": "address" + } + ], + "name": "LogChangeIssuanceAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_allowAllTransfers", + "type": "bool" + } + ], + "name": "LogAllowAllTransfers", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_allowAllWhitelistTransfers", + "type": "bool" + } + ], + "name": "LogAllowAllWhitelistTransfers", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_allowAllWhitelistIssuances", + "type": "bool" + } + ], + "name": "LogAllowAllWhitelistIssuances", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_allowAllBurnTransfers", + "type": "bool" + } + ], + "name": "LogAllowAllBurnTransfers", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_signingAddress", + "type": "address" + } + ], + "name": "LogChangeSigningAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_investor", + "type": "address" + }, + { + "indexed": false, + "name": "_dateAdded", + "type": "uint256" + }, + { + "indexed": false, + "name": "_addedBy", + "type": "address" + }, + { + "indexed": false, + "name": "_fromTime", + "type": "uint256" + }, + { + "indexed": false, + "name": "_toTime", + "type": "uint256" + }, + { + "indexed": false, + "name": "_expiryTime", + "type": "uint256" + }, + { + "indexed": false, + "name": "_canBuyFromSTO", + "type": "bool" + } + ], + "name": "LogModifyWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_timestammp", + "type": "uint256" + } + ], + "name": "Pause", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "Unpause", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "getInitFunction", + "outputs": [ + { + "name": "", + "type": "bytes4" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_issuanceAddress", + "type": "address" + } + ], + "name": "changeIssuanceAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_signingAddress", + "type": "address" + } + ], + "name": "changeSigningAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_allowAllTransfers", + "type": "bool" + } + ], + "name": "changeAllowAllTransfers", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_allowAllWhitelistTransfers", + "type": "bool" + } + ], + "name": "changeAllowAllWhitelistTransfers", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_allowAllWhitelistIssuances", + "type": "bool" + } + ], + "name": "changeAllowAllWhitelistIssuances", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_allowAllBurnTransfers", + "type": "bool" + } + ], + "name": "changeAllowAllBurnTransfers", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "bool" + } + ], + "name": "verifyTransfer", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_investor", + "type": "address" + }, + { + "name": "_fromTime", + "type": "uint256" + }, + { + "name": "_toTime", + "type": "uint256" + }, + { + "name": "_expiryTime", + "type": "uint256" + }, + { + "name": "_canBuyFromSTO", + "type": "bool" + } + ], + "name": "modifyWhitelist", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_investors", + "type": "address[]" + }, + { + "name": "_fromTimes", + "type": "uint256[]" + }, + { + "name": "_toTimes", + "type": "uint256[]" + }, + { + "name": "_expiryTimes", + "type": "uint256[]" + }, + { + "name": "_canBuyFromSTO", + "type": "bool[]" + } + ], + "name": "modifyWhitelistMulti", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_investor", + "type": "address" + }, + { + "name": "_fromTime", + "type": "uint256" + }, + { + "name": "_toTime", + "type": "uint256" + }, + { + "name": "_expiryTime", + "type": "uint256" + }, + { + "name": "_canBuyFromSTO", + "type": "bool" + }, + { + "name": "_validFrom", + "type": "uint256" + }, + { + "name": "_validTo", + "type": "uint256" + }, + { + "name": "_v", + "type": "uint8" + }, + { + "name": "_r", + "type": "bytes32" + }, + { + "name": "_s", + "type": "bytes32" + } + ], + "name": "modifyWhitelistSigned", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getPermissions", + "outputs": [ + { + "name": "", + "type": "bytes32[]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60806040526002805460a060020a60ff021916905560038054600160a060020a03199081169091556004805490911690556006805463ff0000001962ffffff19909116620100001716905534801561005657600080fd5b5060405160408061287d83398101604052805160209091015160018054600160a060020a03938416600160a060020a03199182161790915560008054821633179055600280549390921692169190911790556127c6806100b76000396000f30060806040526004361061015b5763ffffffff60e060020a60003504166307592f6081146101605780630f28937c146101a5578063144b8afa146102de5780631613ec9d146103075780631bb7cc99146103515780632909a80e146103785780633f0547bb1461038d5780633f4ba83a146103a75780634caaf45f146103bc5780635c975abb146103dd5780635f7619a4146103f25780636faa22a51461040a5780637915c9e01461043b5780637ecc866f1461048e5780638456cb59146104a85780639332b62c146104bd5780639728538f146104d75780639b19251a146104ec578063b1dd811114610535578063b3e82dc91461054a578063b3fac8ce1461055f578063b84dfbd214610574578063c3a07df614610589578063c45a0155146105ee578063d70afa9614610603578063d7604a7814610618578063e0c6815814610647578063e55d0f8b14610668578063e8a28d521461067d575b600080fd5b34801561016c57600080fd5b506101a3600160a060020a0360043516602435604435606435608435151560a43560c43560ff60e435166101043561012435610697565b005b3480156101b157600080fd5b50604080516020600480358082013583810280860185019096528085526101a395369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506109689650505050505050565b3480156102ea57600080fd5b506102f3610cf8565b604080519115158252519081900360200190f35b34801561031357600080fd5b5061031c610d08565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b34801561035d57600080fd5b50610366610d0d565b60408051918252519081900360200190f35b34801561038457600080fd5b506102f3610d1f565b34801561039957600080fd5b506101a36004351515610d2d565b3480156103b357600080fd5b506101a3610efa565b3480156103c857600080fd5b506101a3600160a060020a0360043516610fe2565b3480156103e957600080fd5b506102f36111c9565b3480156103fe57600080fd5b506102f36004356111d9565b34801561041657600080fd5b5061041f6114f5565b60408051600160a060020a039092168252519081900360200190f35b34801561044757600080fd5b5061046a600160a060020a03600435811690602435166044356064351515611504565b6040518082600381111561047a57fe5b60ff16815260200191505060405180910390f35b34801561049a57600080fd5b506101a3600435151561167d565b3480156104b457600080fd5b506101a3611854565b3480156104c957600080fd5b506101a3600435151561193a565b3480156104e357600080fd5b50610366611b0f565b3480156104f857600080fd5b5061050d600160a060020a0360043516611b1e565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b34801561054157600080fd5b506102f3611b48565b34801561055657600080fd5b5061041f611b51565b34801561056b57600080fd5b5061041f611b60565b34801561058057600080fd5b5061041f611b6f565b34801561059557600080fd5b5061059e611b7e565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156105da5781810151838201526020016105c2565b505050509050019250505060405180910390f35b3480156105fa57600080fd5b5061041f611bf8565b34801561060f57600080fd5b50610366611c07565b34801561062457600080fd5b506101a3600160a060020a03600435166024356044356064356084351515611c2b565b34801561065357600080fd5b506101a3600160a060020a0360043516611ed4565b34801561067457600080fd5b506102f36120bb565b34801561068957600080fd5b506101a360043515156120ca565b6000428611156106f1576040805160e560020a62461bcd02815260206004820152601660248201527f56616c696446726f6d20697320746f6f206561726c7900000000000000000000604482015290519081900360640190fd5b42851015610749576040805160e560020a62461bcd02815260206004820152601360248201527f56616c6964546f20697320746f6f206c61746500000000000000000000000000604482015290519081900360640190fd5b604080516c01000000000000000000000000308102602080840191909152600160a060020a038f169091026034830152604882018d9052606882018c9052608882018b90527f01000000000000000000000000000000000000000000000000000000000000008a15150260a883015260a9820189905260c98083018990528351808403909101815260e990920192839052815191929182918401908083835b602083106108075780518252601f1990920191602091820191016107e8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050610842818585856122a3565b6080604051908101604052808b81526020018a8152602001898152602001881515815250600560008d600160a060020a0316600160a060020a0316815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff0219169083151502179055509050507f7a985b3a91e6a809b9457eb0e56c26c57186f124ae7e661ef14fa3518d49cdba8b42338d8d8d8d6040518088600160a060020a0316600160a060020a0316815260200187815260200186600160a060020a0316600160a060020a031681526020018581526020018481526020018381526020018215151515815260200197505050505050505060405180910390a15050505050505050505050565b600060008051602061275b833981519152600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156109cf57600080fd5b505af11580156109e3573d6000803e3d6000fd5b505050506040513d60208110156109f957600080fd5b505160005433600160a060020a039283168114945091161490508180610a1c5750805b80610aac57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015610a7f57600080fd5b505af1158015610a93573d6000803e3d6000fd5b505050506040513d6020811015610aa957600080fd5b50515b1515610af0576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b8751895114610b49576040805160e560020a62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b8651885114610ba2576040805160e560020a62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b8551875114610bfb576040805160e560020a62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b8651855114610c54576040805160e560020a62461bcd02815260206004820152601760248201527f4d69736d61746368656420696e707574206c656e677468000000000000000000604482015290519081900360640190fd5b600093505b8851841015610ced57610ce28985815181101515610c7357fe5b906020019060200201518986815181101515610c8b57fe5b906020019060200201518987815181101515610ca357fe5b906020019060200201518988815181101515610cbb57fe5b906020019060200201518989815181101515610cd357fe5b90602001906020020151611c2b565b600190930192610c59565b505050505050505050565b6006546301000000900460ff1681565b600090565b60008051602061275b83398151915281565b600654610100900460ff1681565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610d8f57600080fd5b505af1158015610da3573d6000803e3d6000fd5b505050506040513d6020811015610db957600080fd5b505160005433600160a060020a039283168114945091161490508180610ddc5750805b80610e6c57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015610e3f57600080fd5b505af1158015610e53573d6000803e3d6000fd5b505050506040513d6020811015610e6957600080fd5b50515b1515610eb0576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b6006805485151560ff19909116811790915560408051918252517f185556241b5bd01bdb7ff63397b8990ec8d33116f15a7d7eb5f2b8f7072e1d499181900360200190a150505050565b600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f4d57600080fd5b505af1158015610f61573d6000803e3d6000fd5b505050506040513d6020811015610f7757600080fd5b5051600160a060020a03163314610fd8576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b610fe06124bc565b565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561104457600080fd5b505af1158015611058573d6000803e3d6000fd5b505050506040513d602081101561106e57600080fd5b505160005433600160a060020a0392831681149450911614905081806110915750805b8061112157506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b1580156110f457600080fd5b505af1158015611108573d6000803e3d6000fd5b505050506040513d602081101561111e57600080fd5b50515b1515611165576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60048054600160a060020a03861673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f5940b3e4196e0af34b25de54a6476219b7065395349f15fb84006511fd962d329181900360200190a150505050565b60025460a060020a900460ff1681565b60007f4645455f41444d494e0000000000000000000000000000000000000000000000600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561125257600080fd5b505af1158015611266573d6000803e3d6000fd5b505050506040513d602081101561127c57600080fd5b505160005433600160a060020a03928316811494509116149050818061129f5750805b8061132f57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b15801561130257600080fd5b505af1158015611316573d6000803e3d6000fd5b505050506040513d602081101561132c57600080fd5b50515b1515611373576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60025460015460008054604080517f8da5cb5b0000000000000000000000000000000000000000000000000000000081529051600160a060020a03958616956323b872dd95811694931692638da5cb5b92600480820193602093909283900390910190829087803b1580156113e757600080fd5b505af11580156113fb573d6000803e3d6000fd5b505050506040513d602081101561141157600080fd5b50516040805160e060020a63ffffffff8616028152600160a060020a039384166004820152929091166024830152604482018990525160648083019260209291908290030181600087803b15801561146857600080fd5b505af115801561147c573d6000803e3d6000fd5b505050506040513d602081101561149257600080fd5b505115156114ea576040805160e560020a62461bcd02815260206004820152601260248201527f556e61626c6520746f2074616b65206665650000000000000000000000000000604482015290519081900360640190fd5b506001949350505050565b600254600160a060020a031681565b60025460009060a060020a900460ff1615156114ea5760065460ff161561152d57506002611675565b6006546301000000900460ff16801561154d5750600160a060020a038416155b1561155a57506002611675565b600654610100900460ff16156115985761157384612572565b8015611583575061158385612572565b61158e576001611591565b60025b9050611675565b60065462010000900460ff1680156115bd5750600354600160a060020a038681169116145b1561160757600160a060020a03841660009081526005602052604090206003015460ff161580156115f157506115f16125df565b156115fe57506001611675565b61158384612572565b61161085612572565b80156116345750600160a060020a0385166000908152600560205260409020544210155b8015611583575061164484612572565b80156115835750600160a060020a03841660009081526005602052604090206001015442101561158e576001611591565b949350505050565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156116df57600080fd5b505af11580156116f3573d6000803e3d6000fd5b505050506040513d602081101561170957600080fd5b505160005433600160a060020a03928316811494509116149050818061172c5750805b806117bc57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b15801561178f57600080fd5b505af11580156117a3573d6000803e3d6000fd5b505050506040513d60208110156117b957600080fd5b50515b1515611800576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b6006805485151562010000810262ff0000199092169190911790915560408051918252517f4b711350abee425bbbbd22b0a6615df775a36f2838168ca64da9177ad8fec1609181900360200190a150505050565b600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156118a757600080fd5b505af11580156118bb573d6000803e3d6000fd5b505050506040513d60208110156118d157600080fd5b5051600160a060020a03163314611932576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b610fe061269f565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561199c57600080fd5b505af11580156119b0573d6000803e3d6000fd5b505050506040513d60208110156119c657600080fd5b505160005433600160a060020a0392831681149450911614905081806119e95750805b80611a7957506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015611a4c57600080fd5b505af1158015611a60573d6000803e3d6000fd5b505050506040513d6020811015611a7657600080fd5b50515b1515611abd576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60068054851515610100810261ff00199092169190911790915560408051918252517f7544dcc0388a2e2a001b92ece53af2e1e3135973ff37e5dcd80a12cf5ed2b4259181900360200190a150505050565b60d860020a64464c4147530281565b60056020526000908152604090208054600182015460028301546003909301549192909160ff1684565b60065460ff1681565b600454600160a060020a031681565b600354600160a060020a031681565b600154600160a060020a031681565b60408051600280825260608083018452928392919060208301908038833901905050905060008051602061275b833981519152816000815181101515611bc057fe5b60209081029091010152805160d860020a64464c414753029082906001908110611be657fe5b602090810290910101529050805b5090565b600054600160a060020a031681565b7f4645455f41444d494e000000000000000000000000000000000000000000000081565b60008051602061275b833981519152600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c9057600080fd5b505af1158015611ca4573d6000803e3d6000fd5b505050506040513d6020811015611cba57600080fd5b505160005433600160a060020a039283168114945091161490508180611cdd5750805b80611d6d57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015611d4057600080fd5b505af1158015611d54573d6000803e3d6000fd5b505050506040513d6020811015611d6a57600080fd5b50515b1515611db1576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b608060405190810160405280888152602001878152602001868152602001851515815250600560008a600160a060020a0316600160a060020a0316815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff0219169083151502179055509050507f7a985b3a91e6a809b9457eb0e56c26c57186f124ae7e661ef14fa3518d49cdba8842338a8a8a8a6040518088600160a060020a0316600160a060020a0316815260200187815260200186600160a060020a0316600160a060020a031681526020018581526020018481526020018381526020018215151515815260200197505050505050505060405180910390a15050505050505050565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611f3657600080fd5b505af1158015611f4a573d6000803e3d6000fd5b505050506040513d6020811015611f6057600080fd5b505160005433600160a060020a039283168114945091161490508180611f835750805b8061201357506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015611fe657600080fd5b505af1158015611ffa573d6000803e3d6000fd5b505050506040513d602081101561201057600080fd5b50515b1515612057576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60038054600160a060020a03861673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f0e2eb0247b22c29b3f02a9a2b65eae999b4117981e84dc701ce1fb6830a6ac5f9181900360200190a150505050565b60065462010000900460ff1681565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561212c57600080fd5b505af1158015612140573d6000803e3d6000fd5b505050506040513d602081101561215657600080fd5b505160005433600160a060020a0392831681149450911614905081806121795750805b8061220957506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b1580156121dc57600080fd5b505af11580156121f0573d6000803e3d6000fd5b505050506040513d602081101561220657600080fd5b50515b151561224d576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b600680548515156301000000810263ff000000199092169190911790915560408051918252517f1234a547e9a90612dd64cdca6ea7120623490ff57b5762b1e6f7bec9a81aaa409181900360200190a150505050565b600060018560405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b602083106123265780518252601f199092019160209182019101612307565b51815160209384036101000a60001901801990921691161790526040805192909401829003822060008084528383018087529190915260ff8c1683860152606083018b9052608083018a9052935160a08084019750919550601f1981019492819003909101925090865af11580156123a2573d6000803e3d6000fd5b505060408051601f198101516001547f8da5cb5b0000000000000000000000000000000000000000000000000000000083529251909450600160a060020a039092169250638da5cb5b9160048083019260209291908290030181600087803b15801561240d57600080fd5b505af1158015612421573d6000803e3d6000fd5b505050506040513d602081101561243757600080fd5b5051600160a060020a038281169116148061245f5750600454600160a060020a038281169116145b15156124b5576040805160e560020a62461bcd02815260206004820152601060248201527f496e636f7272656374207369676e657200000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b60025460a060020a900460ff16151561251f576040805160e560020a62461bcd02815260206004820152601660248201527f436f6e7472616374206973206e6f742070617573656400000000000000000000604482015290519081900360640190fd5b6002805474ff0000000000000000000000000000000000000000191690556040805142815290517faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab79181900360200190a1565b600160a060020a0381166000908152600560205260408120541515806125b25750600160a060020a03821660009081526005602052604090206001015415155b80156125d95750600160a060020a0382166000908152600560205260409020600201544211155b92915050565b600154604080517f46b65ffd00000000000000000000000000000000000000000000000000000000815260036004820152600060248201819052825190938493600160a060020a03909116926346b65ffd926044808301939282900301818787803b15801561264d57600080fd5b505af1158015612661573d6000803e3d6000fd5b505050506040513d604081101561267757600080fd5b50602001519050600160a060020a03811615156126975760009150611bf4565b600191505090565b60025460a060020a900460ff1615612701576040805160e560020a62461bcd02815260206004820152601260248201527f436f6e7472616374206973207061757365640000000000000000000000000000604482015290519081900360640190fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a1790556040805142815290517f68b095021b1f40fe513109f513c66692f0b3219aee674a69f4efc57badb8201d9181900360200190a1560057484954454c49535400000000000000000000000000000000000000000000005065726d697373696f6e20636865636b206661696c6564000000000000000000a165627a7a723058209c60477be9e3335d7513cb31a770acea9031396b331e327cbc7d528ceaff333e0029", + "deployedBytecode": "0x60806040526004361061015b5763ffffffff60e060020a60003504166307592f6081146101605780630f28937c146101a5578063144b8afa146102de5780631613ec9d146103075780631bb7cc99146103515780632909a80e146103785780633f0547bb1461038d5780633f4ba83a146103a75780634caaf45f146103bc5780635c975abb146103dd5780635f7619a4146103f25780636faa22a51461040a5780637915c9e01461043b5780637ecc866f1461048e5780638456cb59146104a85780639332b62c146104bd5780639728538f146104d75780639b19251a146104ec578063b1dd811114610535578063b3e82dc91461054a578063b3fac8ce1461055f578063b84dfbd214610574578063c3a07df614610589578063c45a0155146105ee578063d70afa9614610603578063d7604a7814610618578063e0c6815814610647578063e55d0f8b14610668578063e8a28d521461067d575b600080fd5b34801561016c57600080fd5b506101a3600160a060020a0360043516602435604435606435608435151560a43560c43560ff60e435166101043561012435610697565b005b3480156101b157600080fd5b50604080516020600480358082013583810280860185019096528085526101a395369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506109689650505050505050565b3480156102ea57600080fd5b506102f3610cf8565b604080519115158252519081900360200190f35b34801561031357600080fd5b5061031c610d08565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b34801561035d57600080fd5b50610366610d0d565b60408051918252519081900360200190f35b34801561038457600080fd5b506102f3610d1f565b34801561039957600080fd5b506101a36004351515610d2d565b3480156103b357600080fd5b506101a3610efa565b3480156103c857600080fd5b506101a3600160a060020a0360043516610fe2565b3480156103e957600080fd5b506102f36111c9565b3480156103fe57600080fd5b506102f36004356111d9565b34801561041657600080fd5b5061041f6114f5565b60408051600160a060020a039092168252519081900360200190f35b34801561044757600080fd5b5061046a600160a060020a03600435811690602435166044356064351515611504565b6040518082600381111561047a57fe5b60ff16815260200191505060405180910390f35b34801561049a57600080fd5b506101a3600435151561167d565b3480156104b457600080fd5b506101a3611854565b3480156104c957600080fd5b506101a3600435151561193a565b3480156104e357600080fd5b50610366611b0f565b3480156104f857600080fd5b5061050d600160a060020a0360043516611b1e565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b34801561054157600080fd5b506102f3611b48565b34801561055657600080fd5b5061041f611b51565b34801561056b57600080fd5b5061041f611b60565b34801561058057600080fd5b5061041f611b6f565b34801561059557600080fd5b5061059e611b7e565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156105da5781810151838201526020016105c2565b505050509050019250505060405180910390f35b3480156105fa57600080fd5b5061041f611bf8565b34801561060f57600080fd5b50610366611c07565b34801561062457600080fd5b506101a3600160a060020a03600435166024356044356064356084351515611c2b565b34801561065357600080fd5b506101a3600160a060020a0360043516611ed4565b34801561067457600080fd5b506102f36120bb565b34801561068957600080fd5b506101a360043515156120ca565b6000428611156106f1576040805160e560020a62461bcd02815260206004820152601660248201527f56616c696446726f6d20697320746f6f206561726c7900000000000000000000604482015290519081900360640190fd5b42851015610749576040805160e560020a62461bcd02815260206004820152601360248201527f56616c6964546f20697320746f6f206c61746500000000000000000000000000604482015290519081900360640190fd5b604080516c01000000000000000000000000308102602080840191909152600160a060020a038f169091026034830152604882018d9052606882018c9052608882018b90527f01000000000000000000000000000000000000000000000000000000000000008a15150260a883015260a9820189905260c98083018990528351808403909101815260e990920192839052815191929182918401908083835b602083106108075780518252601f1990920191602091820191016107e8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050610842818585856122a3565b6080604051908101604052808b81526020018a8152602001898152602001881515815250600560008d600160a060020a0316600160a060020a0316815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff0219169083151502179055509050507f7a985b3a91e6a809b9457eb0e56c26c57186f124ae7e661ef14fa3518d49cdba8b42338d8d8d8d6040518088600160a060020a0316600160a060020a0316815260200187815260200186600160a060020a0316600160a060020a031681526020018581526020018481526020018381526020018215151515815260200197505050505050505060405180910390a15050505050505050505050565b600060008051602061275b833981519152600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156109cf57600080fd5b505af11580156109e3573d6000803e3d6000fd5b505050506040513d60208110156109f957600080fd5b505160005433600160a060020a039283168114945091161490508180610a1c5750805b80610aac57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015610a7f57600080fd5b505af1158015610a93573d6000803e3d6000fd5b505050506040513d6020811015610aa957600080fd5b50515b1515610af0576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b8751895114610b49576040805160e560020a62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b8651885114610ba2576040805160e560020a62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b8551875114610bfb576040805160e560020a62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b8651855114610c54576040805160e560020a62461bcd02815260206004820152601760248201527f4d69736d61746368656420696e707574206c656e677468000000000000000000604482015290519081900360640190fd5b600093505b8851841015610ced57610ce28985815181101515610c7357fe5b906020019060200201518986815181101515610c8b57fe5b906020019060200201518987815181101515610ca357fe5b906020019060200201518988815181101515610cbb57fe5b906020019060200201518989815181101515610cd357fe5b90602001906020020151611c2b565b600190930192610c59565b505050505050505050565b6006546301000000900460ff1681565b600090565b60008051602061275b83398151915281565b600654610100900460ff1681565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610d8f57600080fd5b505af1158015610da3573d6000803e3d6000fd5b505050506040513d6020811015610db957600080fd5b505160005433600160a060020a039283168114945091161490508180610ddc5750805b80610e6c57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015610e3f57600080fd5b505af1158015610e53573d6000803e3d6000fd5b505050506040513d6020811015610e6957600080fd5b50515b1515610eb0576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b6006805485151560ff19909116811790915560408051918252517f185556241b5bd01bdb7ff63397b8990ec8d33116f15a7d7eb5f2b8f7072e1d499181900360200190a150505050565b600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f4d57600080fd5b505af1158015610f61573d6000803e3d6000fd5b505050506040513d6020811015610f7757600080fd5b5051600160a060020a03163314610fd8576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b610fe06124bc565b565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561104457600080fd5b505af1158015611058573d6000803e3d6000fd5b505050506040513d602081101561106e57600080fd5b505160005433600160a060020a0392831681149450911614905081806110915750805b8061112157506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b1580156110f457600080fd5b505af1158015611108573d6000803e3d6000fd5b505050506040513d602081101561111e57600080fd5b50515b1515611165576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60048054600160a060020a03861673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f5940b3e4196e0af34b25de54a6476219b7065395349f15fb84006511fd962d329181900360200190a150505050565b60025460a060020a900460ff1681565b60007f4645455f41444d494e0000000000000000000000000000000000000000000000600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561125257600080fd5b505af1158015611266573d6000803e3d6000fd5b505050506040513d602081101561127c57600080fd5b505160005433600160a060020a03928316811494509116149050818061129f5750805b8061132f57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b15801561130257600080fd5b505af1158015611316573d6000803e3d6000fd5b505050506040513d602081101561132c57600080fd5b50515b1515611373576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60025460015460008054604080517f8da5cb5b0000000000000000000000000000000000000000000000000000000081529051600160a060020a03958616956323b872dd95811694931692638da5cb5b92600480820193602093909283900390910190829087803b1580156113e757600080fd5b505af11580156113fb573d6000803e3d6000fd5b505050506040513d602081101561141157600080fd5b50516040805160e060020a63ffffffff8616028152600160a060020a039384166004820152929091166024830152604482018990525160648083019260209291908290030181600087803b15801561146857600080fd5b505af115801561147c573d6000803e3d6000fd5b505050506040513d602081101561149257600080fd5b505115156114ea576040805160e560020a62461bcd02815260206004820152601260248201527f556e61626c6520746f2074616b65206665650000000000000000000000000000604482015290519081900360640190fd5b506001949350505050565b600254600160a060020a031681565b60025460009060a060020a900460ff1615156114ea5760065460ff161561152d57506002611675565b6006546301000000900460ff16801561154d5750600160a060020a038416155b1561155a57506002611675565b600654610100900460ff16156115985761157384612572565b8015611583575061158385612572565b61158e576001611591565b60025b9050611675565b60065462010000900460ff1680156115bd5750600354600160a060020a038681169116145b1561160757600160a060020a03841660009081526005602052604090206003015460ff161580156115f157506115f16125df565b156115fe57506001611675565b61158384612572565b61161085612572565b80156116345750600160a060020a0385166000908152600560205260409020544210155b8015611583575061164484612572565b80156115835750600160a060020a03841660009081526005602052604090206001015442101561158e576001611591565b949350505050565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156116df57600080fd5b505af11580156116f3573d6000803e3d6000fd5b505050506040513d602081101561170957600080fd5b505160005433600160a060020a03928316811494509116149050818061172c5750805b806117bc57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b15801561178f57600080fd5b505af11580156117a3573d6000803e3d6000fd5b505050506040513d60208110156117b957600080fd5b50515b1515611800576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b6006805485151562010000810262ff0000199092169190911790915560408051918252517f4b711350abee425bbbbd22b0a6615df775a36f2838168ca64da9177ad8fec1609181900360200190a150505050565b600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156118a757600080fd5b505af11580156118bb573d6000803e3d6000fd5b505050506040513d60208110156118d157600080fd5b5051600160a060020a03163314611932576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b610fe061269f565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561199c57600080fd5b505af11580156119b0573d6000803e3d6000fd5b505050506040513d60208110156119c657600080fd5b505160005433600160a060020a0392831681149450911614905081806119e95750805b80611a7957506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015611a4c57600080fd5b505af1158015611a60573d6000803e3d6000fd5b505050506040513d6020811015611a7657600080fd5b50515b1515611abd576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60068054851515610100810261ff00199092169190911790915560408051918252517f7544dcc0388a2e2a001b92ece53af2e1e3135973ff37e5dcd80a12cf5ed2b4259181900360200190a150505050565b60d860020a64464c4147530281565b60056020526000908152604090208054600182015460028301546003909301549192909160ff1684565b60065460ff1681565b600454600160a060020a031681565b600354600160a060020a031681565b600154600160a060020a031681565b60408051600280825260608083018452928392919060208301908038833901905050905060008051602061275b833981519152816000815181101515611bc057fe5b60209081029091010152805160d860020a64464c414753029082906001908110611be657fe5b602090810290910101529050805b5090565b600054600160a060020a031681565b7f4645455f41444d494e000000000000000000000000000000000000000000000081565b60008051602061275b833981519152600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c9057600080fd5b505af1158015611ca4573d6000803e3d6000fd5b505050506040513d6020811015611cba57600080fd5b505160005433600160a060020a039283168114945091161490508180611cdd5750805b80611d6d57506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015611d4057600080fd5b505af1158015611d54573d6000803e3d6000fd5b505050506040513d6020811015611d6a57600080fd5b50515b1515611db1576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b608060405190810160405280888152602001878152602001868152602001851515815250600560008a600160a060020a0316600160a060020a0316815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff0219169083151502179055509050507f7a985b3a91e6a809b9457eb0e56c26c57186f124ae7e661ef14fa3518d49cdba8842338a8a8a8a6040518088600160a060020a0316600160a060020a0316815260200187815260200186600160a060020a0316600160a060020a031681526020018581526020018481526020018381526020018215151515815260200197505050505050505060405180910390a15050505050505050565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611f3657600080fd5b505af1158015611f4a573d6000803e3d6000fd5b505050506040513d6020811015611f6057600080fd5b505160005433600160a060020a039283168114945091161490508180611f835750805b8061201357506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b158015611fe657600080fd5b505af1158015611ffa573d6000803e3d6000fd5b505050506040513d602081101561201057600080fd5b50515b1515612057576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b60038054600160a060020a03861673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f0e2eb0247b22c29b3f02a9a2b65eae999b4117981e84dc701ce1fb6830a6ac5f9181900360200190a150505050565b60065462010000900460ff1681565b60d860020a64464c41475302600080600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561212c57600080fd5b505af1158015612140573d6000803e3d6000fd5b505050506040513d602081101561215657600080fd5b505160005433600160a060020a0392831681149450911614905081806121795750805b8061220957506001546040805160e060020a638658b8b9028152336004820152306024820152604481018690529051600160a060020a0390921691638658b8b9916064808201926020929091908290030181600087803b1580156121dc57600080fd5b505af11580156121f0573d6000803e3d6000fd5b505050506040513d602081101561220657600080fd5b50515b151561224d576040805160e560020a62461bcd028152602060048201526017602482015260008051602061277b833981519152604482015290519081900360640190fd5b600680548515156301000000810263ff000000199092169190911790915560408051918252517f1234a547e9a90612dd64cdca6ea7120623490ff57b5762b1e6f7bec9a81aaa409181900360200190a150505050565b600060018560405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b602083106123265780518252601f199092019160209182019101612307565b51815160209384036101000a60001901801990921691161790526040805192909401829003822060008084528383018087529190915260ff8c1683860152606083018b9052608083018a9052935160a08084019750919550601f1981019492819003909101925090865af11580156123a2573d6000803e3d6000fd5b505060408051601f198101516001547f8da5cb5b0000000000000000000000000000000000000000000000000000000083529251909450600160a060020a039092169250638da5cb5b9160048083019260209291908290030181600087803b15801561240d57600080fd5b505af1158015612421573d6000803e3d6000fd5b505050506040513d602081101561243757600080fd5b5051600160a060020a038281169116148061245f5750600454600160a060020a038281169116145b15156124b5576040805160e560020a62461bcd02815260206004820152601060248201527f496e636f7272656374207369676e657200000000000000000000000000000000604482015290519081900360640190fd5b5050505050565b60025460a060020a900460ff16151561251f576040805160e560020a62461bcd02815260206004820152601660248201527f436f6e7472616374206973206e6f742070617573656400000000000000000000604482015290519081900360640190fd5b6002805474ff0000000000000000000000000000000000000000191690556040805142815290517faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab79181900360200190a1565b600160a060020a0381166000908152600560205260408120541515806125b25750600160a060020a03821660009081526005602052604090206001015415155b80156125d95750600160a060020a0382166000908152600560205260409020600201544211155b92915050565b600154604080517f46b65ffd00000000000000000000000000000000000000000000000000000000815260036004820152600060248201819052825190938493600160a060020a03909116926346b65ffd926044808301939282900301818787803b15801561264d57600080fd5b505af1158015612661573d6000803e3d6000fd5b505050506040513d604081101561267757600080fd5b50602001519050600160a060020a03811615156126975760009150611bf4565b600191505090565b60025460a060020a900460ff1615612701576040805160e560020a62461bcd02815260206004820152601260248201527f436f6e7472616374206973207061757365640000000000000000000000000000604482015290519081900360640190fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a1790556040805142815290517f68b095021b1f40fe513109f513c66692f0b3219aee674a69f4efc57badb8201d9181900360200190a1560057484954454c49535400000000000000000000000000000000000000000000005065726d697373696f6e20636865636b206661696c6564000000000000000000a165627a7a723058209c60477be9e3335d7513cb31a770acea9031396b331e327cbc7d528ceaff333e0029", + "sourceMap": "759:13030:47:-;;;216:26:1;;;-1:-1:-1;;;;;;216:26:1;;;891:43:47;;;-1:-1:-1;;;;;;891:43:47;;;;;;988:42;;;;;;;;1669:37;;;-1:-1:-1;;;;1938:45:47;;;;;2047:41;;;3408:123;5:2:-1;;;;30:1;27;20:12;5:2;3408:123:47;;;;;;;;;;;;;;;;;;;624:13:12;:30;;-1:-1:-1;;;;;624:30:12;;;-1:-1:-1;;;;;;624:30:12;;;;;;;:13;664:20;;;;674:10;664:20;;;694:9;:31;;;;;;;;;;;;;;759:13030:47;;;;;;", + "deployedSourceMap": "759:13030:47:-;;;;;;;;-1:-1:-1;759:13030:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11191:912;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;11191:912:47;;;-1:-1:-1;;;;;11191:912:47;;;;;;;;;;;;;;;;;;;;;;;;;;;9584:736;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9584:736:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9584:736:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9584:736:47;;;;-1:-1:-1;9584:736:47;-1:-1:-1;9584:736:47;;-1:-1:-1;9584:736:47;;;;;;;;;-1:-1:-1;;9584:736:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9584:736:47;;;;-1:-1:-1;9584:736:47;-1:-1:-1;9584:736:47;;-1:-1:-1;9584:736:47;;;;;;;;;-1:-1:-1;;9584:736:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9584:736:47;;;;-1:-1:-1;9584:736:47;-1:-1:-1;9584:736:47;;-1:-1:-1;9584:736:47;;;;;;;;;-1:-1:-1;;9584:736:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9584:736:47;;;;-1:-1:-1;9584:736:47;-1:-1:-1;9584:736:47;;-1:-1:-1;9584:736:47;;;;;;;;;-1:-1:-1;9584:736:47;;-1:-1:-1;9584:736:47;;-1:-1:-1;;;;;;;9584:736:47;2047:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2047:41:47;;;;;;;;;;;;;;;;;;;;;;3626:89;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3626:89:47;;;;;;;;;;;;;;;;;;;;;;;1037:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1037:47:47;;;;;;;;;;;;;;;;;;;;1799:46;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1799:46:47;;;;4611:191;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4611:191:47;;;;;;;711:69:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;711:69:49;;;;4167:182:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;4167:182:47;;;-1:-1:-1;;;;;4167:182:47;;;216:26:1;;8:9:-1;5:2;;;30:1;27;20:12;5:2;216:26:1;;;;1890:223:12;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1890:223:12;;;;;365:22;;8:9:-1;5:2;;;30:1;27;20:12;5:2;365:22:12;;;;;;;;-1:-1:-1;;;;;365:22:12;;;;;;;;;;;;;;6703:1241:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6703:1241:47;-1:-1:-1;;;;;6703:1241:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5635:245;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5635:245:47;;;;;;;786:65:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;786:65:49;;;;5096:245:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;5096:245:47;;;;;;;1090:39;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1090:39:47;;;;1540:53;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1540:53:47;;;-1:-1:-1;;;;;1540:53:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1669:37;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1669:37:47;;;;988:42;;8:9:-1;5:2;;;30:1;27;20:12;5:2;988:42:47;;;;891:43;;8:9:-1;5:2;;;30:1;27;20:12;5:2;891:43:47;;;;276:28:12;;8:9:-1;5:2;;;30:1;27;20:12;5:2;276:28:12;;;;12764:229:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12764:229:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;12764:229:47;;;;;;;;;;;;;;;;;247:22:12;;8:9:-1;5:2;;;30:1;27;20:12;5:2;247:22:12;;;;311:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;311:47:12;;;;8529:473:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8529:473:47;;;-1:-1:-1;;;;;8529:473:47;;;;;;;;;;;;;3848:188;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3848:188:47;;;-1:-1:-1;;;;;3848:188:47;;;1938:45;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1938:45:47;;;;6093:215;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6093:215:47;;;;;;;11191:912;11613:12;11516:3;11502:17;;;11494:52;;;;;-1:-1:-1;;;;;11494:52:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;11576:3;11564:15;;;11556:47;;;;;-1:-1:-1;;;;;11556:47:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;11638:104;;;;11655:4;11638:104;;;;;;;;;;-1:-1:-1;;;;;11638:104:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;11638:104:47;;;;;;;;11628:115;;11638:104;;;;;11628:115;;;;11638:104;11628:115;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;11628:115:47;;;;;;;;;;;;;;;;11613:130;;11753:26;11762:4;11768:2;11772;11776;11753:8;:26::i;:::-;11922:64;;;;;;;;;11938:9;11922:64;;;;11949:7;11922:64;;;;11958:11;11922:64;;;;11971:14;11922:64;;;;;11899:9;:20;11909:9;-1:-1:-1;;;;;11899:20:47;-1:-1:-1;;;;;11899:20:47;;;;;;;;;;;;:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12001:95;12020:9;12031:3;12036:10;12048:9;12059:7;12068:11;12081:14;12001:95;;;;-1:-1:-1;;;;;12001:95:47;-1:-1:-1;;;;;12001:95:47;;;;;;;;;;;-1:-1:-1;;;;;12001:95:47;-1:-1:-1;;;;;12001:95:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11191:912;;;;;;;;;;;:::o;9584:736::-;10152:9;-1:-1:-1;;;;;;;;;;;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;-1:-1:-1;1029:13:12;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;9837:17:47;;9816;;:38;9808:75;;;;;-1:-1:-1;;;;;9808:75:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;9922:15;;9901:17;;:36;9893:73;;;;;-1:-1:-1;;;;;9893:73:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;10003:19;;9984:15;;:38;9976:75;;;;;-1:-1:-1;;;;;9976:75:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;10094:15;;10069:21;;:40;10061:76;;;;;-1:-1:-1;;;;;10061:76:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;10164:1;10152:13;;10147:167;10171:10;:17;10167:1;:21;10147:167;;;10209:94;10225:10;10236:1;10225:13;;;;;;;;;;;;;;;;;;10240:10;10251:1;10240:13;;;;;;;;;;;;;;;;;;10255:8;10264:1;10255:11;;;;;;;;;;;;;;;;;;10268:12;10281:1;10268:15;;;;;;;;;;;;;;;;;;10285:14;10300:1;10285:17;;;;;;;;;;;;;;;;;;10209:15;:94::i;:::-;10190:3;;;;;10147:167;;;9584:736;;;;;;;;;:::o;2047:41::-;;;;;;;;;:::o;3626:89::-;3674:6;3626:89;:::o;1037:47::-;-1:-1:-1;;;;;;;;;;;1037:47:47;:::o;1799:46::-;;;;;;;;;:::o;4611:191::-;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;985:12:12;;;;-1:-1:-1;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;985:12;1029:13;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;4702:17:47;:38;;-1:-1:-1;;4702:38:47;;;;;;;;;;4755:40;;;;;;;;;;;;;;;;;4611:191;;;;:::o;711:69:49:-;1334:13:12;;1319:37;;;-1:-1:-1;;;;;1319:37:12;;;;-1:-1:-1;;;;;1334:13:12;;;;1319:35;;:37;;;;;;;;;;;;;;;1334:13;;1319:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1319:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1319:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1319:37:12;-1:-1:-1;;;;;1305:51:12;:10;:51;1297:83;;;;;-1:-1:-1;;;;;1297:83:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;757:16:49;:14;:16::i;:::-;711:69::o;4167:182:47:-;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;985:12:12;;;;-1:-1:-1;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;985:12;1029:13;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;4255:14:47;:32;;-1:-1:-1;;4255:32:47;-1:-1:-1;;;;;4255:32:47;;;;;;;;4302:40;;;;;;;;;;;;;;;;;4167:182;;;;:::o;216:26:1:-;;;-1:-1:-1;216:26:1;;;;;:::o;1890:223:12:-;1029:13;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;1959:4;;1940:9;;1959:4;;;;-1:-1:-1;;;;;1029:13:12;;1014:35;;:37;;;;;;;;;;;;;;1959:4;1029:13;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;1983:9;;;2006:13;1983:9;2036:7;;2021:31;;;-1:-1:-1;;;;;2021:31:12;;;;-1:-1:-1;;;;;1983:9:12;;;;:22;;2006:13;;;2036:7;;;2021:29;;:31;;;;;;;;;;;;;;;;;;2036:7;2021:31;;;5:2:-1;;;;30:1;27;20:12;5:2;2021:31:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2021:31:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2021:31:12;1983:79;;;;;;-1:-1:-1;1983:79:12;;;-1:-1:-1;;;;;1983:79:12;;;;;;;;;;;;;;;;;;;;;;;;;;;2021:31;;1983:79;;;;;;;-1:-1:-1;1983:79:12;;;;5:2:-1;;;;30:1;27;20:12;5:2;1983:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1983:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1983:79:12;1975:110;;;;;;;-1:-1:-1;;;;;1975:110:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2102:4:12;;1890:223;-1:-1:-1;;;;1890:223:12:o;365:22::-;;;-1:-1:-1;;;;;365:22:12;;:::o;6703:1241:47:-;6838:6;;6815;;-1:-1:-1;6838:6:47;;;;6837:7;6833:1079;;;6864:17;;;;6860:140;;;-1:-1:-1;6973:12:47;6966:19;;6860:140;7017:21;;;;;;;:44;;;;-1:-1:-1;;;;;;7043:17:47;;;7017:44;7013:102;;;-1:-1:-1;7088:12:47;7081:19;;7013:102;7132:26;;;;;;;7128:222;;;7269:16;7281:3;7269:11;:16::i;:::-;:38;;;;;7289:18;7301:5;7289:11;:18::i;:::-;7268:67;;7326:9;7268:67;;;7311:12;7268:67;7261:74;;;;7128:222;7367:26;;;;;;;:54;;;;-1:-1:-1;7406:15:47;;-1:-1:-1;;;;;7397:24:47;;;7406:15;;7397:24;7367:54;7363:271;;;-1:-1:-1;;;;;7446:14:47;;;;;;:9;:14;;;;;:28;;;;;7445:29;:48;;;;;7478:15;:13;:15::i;:::-;7441:111;;;-1:-1:-1;7524:9:47;7517:16;;7441:111;7576:16;7588:3;7576:11;:16::i;7363:271::-;7748:18;7760:5;7748:11;:18::i;:::-;:54;;;;-1:-1:-1;;;;;;7770:16:47;;;;;;:9;:16;;;;;:25;7799:3;-1:-1:-1;7770:32:47;7748:54;7747:126;;;;;7824:16;7836:3;7824:11;:16::i;:::-;:48;;;;-1:-1:-1;;;;;;7844:14:47;;;;;;:9;:14;;;;;-1:-1:-1;7844:21:47;;7869:3;-1:-1:-1;7844:28:47;7746:155;;7892:9;7746:155;;6703:1241;;;;;;;:::o;5635:245::-;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;985:12:12;;;;-1:-1:-1;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;985:12;1029:13;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;5744:26:47;:56;;-1:-1:-1;;5744:56:47;;;;;;;;;;;;;;;5815:58;;;;;;;;;;;;;;;;;5635:245;;;;:::o;786:65:49:-;1334:13:12;;1319:37;;;-1:-1:-1;;;;;1319:37:12;;;;-1:-1:-1;;;;;1334:13:12;;;;1319:35;;:37;;;;;;;;;;;;;;;1334:13;;1319:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1319:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1319:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1319:37:12;-1:-1:-1;;;;;1305:51:12;:10;:51;1297:83;;;;;-1:-1:-1;;;;;1297:83:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;830:14:49;:12;:14::i;5096:245:47:-;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;985:12:12;;;;-1:-1:-1;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;985:12;1029:13;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;5205:26:47;:56;;-1:-1:-1;;5205:56:47;;;;;;;;;;;;;;;5276:58;;;;;;;;;;;;;;;;;5096:245;;;;:::o;1090:39::-;-1:-1:-1;;;;;1090:39:47;:::o;1540:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1669:37::-;;;;;;:::o;988:42::-;;;-1:-1:-1;;;;;988:42:47;;:::o;891:43::-;;;-1:-1:-1;;;;;891:43:47;;:::o;276:28:12:-;;;-1:-1:-1;;;;;276:28:12;;:::o;12764:229:47:-;12865:16;;;12879:1;12865:16;;;12810:9;12865:16;;;;;12810:9;;;12865:16;12879:1;12865:16;;;;;105:10:-1;12865:16:47;88:34:-1;136:17;;-1:-1;12865:16:47;12831:50;;-1:-1:-1;;;;;;;;;;;12891:14:47;12906:1;12891:17;;;;;;;;;;;;;;;;;;;:29;12930:17;;-1:-1:-1;;;;;;12930:17:47;;12945:1;;12930:17;;;;;;;;;;;;;;:25;12972:14;-1:-1:-1;12972:14:47;12764:229;;;:::o;247:22:12:-;;;-1:-1:-1;;;;;247:22:12;;:::o;311:47::-;;;:::o;8529:473:47:-;-1:-1:-1;;;;;;;;;;;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;-1:-1:-1;1029:13:12;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;8821:64:47;;;;;;;;;8837:9;8821:64;;;;8848:7;8821:64;;;;8857:11;8821:64;;;;8870:14;8821:64;;;;;8798:9;:20;8808:9;-1:-1:-1;;;;;8798:20:47;-1:-1:-1;;;;;8798:20:47;;;;;;;;;;;;:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8900:95;8919:9;8930:3;8935:10;8947:9;8958:7;8967:11;8980:14;8900:95;;;;-1:-1:-1;;;;;8900:95:47;-1:-1:-1;;;;;8900:95:47;;;;;;;;;;;-1:-1:-1;;;;;8900:95:47;-1:-1:-1;;;;;8900:95:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8529:473;;;;;;;;:::o;3848:188::-;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;985:12:12;;;;-1:-1:-1;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;985:12;1029:13;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;3938:15:47;:34;;-1:-1:-1;;3938:34:47;-1:-1:-1;;;;;3938:34:47;;;;;;;;3987:42;;;;;;;;;;;;;;;;;3848:188;;;;:::o;1938:45::-;;;;;;;;;:::o;6093:215::-;1029:13:12;;1014:37;;;-1:-1:-1;;;;;1014:37:12;;;;-1:-1:-1;;;;;;985:12:12;;;;-1:-1:-1;;;;;1029:13:12;;;;1014:35;;:37;;;;;;;;;;;;;;;985:12;1029:13;1014:37;;;5:2:-1;;;;30:1;27;20:12;5:2;1014:37:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1014:37:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1014:37:12;1092:7;;1000:10;-1:-1:-1;;;;;1000:51:12;;;;;;-1:-1:-1;1092:7:12;;1078:21;;-1:-1:-1;1000:51:12;;1117:18;;;1126:9;1117:18;:99;;;-1:-1:-1;1152:13:12;;1137:79;;;-1:-1:-1;;;;;1137:79:12;;1183:10;1137:79;;;;1203:4;1137:79;;;;;;;;;;;;-1:-1:-1;;;;;1152:13:12;;;;-1:-1:-1;;1137:79:12;;;;;;;;;;;;;;;-1:-1:-1;1152:13:12;1137:79;;;5:2:-1;;;;30:1;27;20:12;5:2;1137:79:12;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1137:79:12;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1137:79:12;1117:99;1109:135;;;;;;;-1:-1:-1;;;;;1109:135:12;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;1109:135:12;;;;;;;;;;;;;;;6192:21:47;:46;;-1:-1:-1;;6192:46:47;;;;;;;;;;;;;;;6253:48;;;;;;;;;;;;;;;;;6093:215;;;;:::o;12169:480::-;12418:14;12435:93;12508:5;12455:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;12455:59:47;;;12445:70;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;-1:-1;;263:2;259:12;;;254:3;250:22;246:30;340:21;;;311:9;;295:26;;;377:20;365:33;;12445:70:47;;;;;;;;;;;;-1:-1:-1;12435:93:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;263:2;;-1:-1;;;12435:93:47;;;;;;;;;;-1:-1:-1;12435:93:47;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;12435:93:47;;;-1:-1:-1;;12435:93:47;;;12571:13;;-1:-1:-1;;;;;12556:37:47;;;;12435:93;;-1:-1:-1;;;;;;12571:13:47;;;;-1:-1:-1;12556:35:47;;:37;;;;;12435:93;;12556:37;;;;;;;-1:-1:-1;12571:13:47;12556:37;;;5:2:-1;;;;30:1;27;20:12;5:2;12556:37:47;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12556:37:47;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12556:37:47;-1:-1:-1;;;;;12546:47:47;;;;;;;:75;;-1:-1:-1;12607:14:47;;-1:-1:-1;;;;;12597:24:47;;;12607:14;;12597:24;12546:75;12538:104;;;;;;;-1:-1:-1;;;;;12538:104:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;12169:480;;;;;:::o;915:98:1:-;590:6;;-1:-1:-1;590:6:1;;;;582:41;;;;;;;-1:-1:-1;;;;;582:41:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;965:6;:14;;-1:-1:-1;;965:14:1;;;994:12;;;1002:3;994:12;;;;;;;;;;;;;915:98::o;13231:226:47:-;-1:-1:-1;;;;;13319:20:47;;13293:4;13319:20;;;:9;:20;;;;;:29;:34;;;13318:74;;-1:-1:-1;;;;;;13359:20:47;;;;;;:9;:20;;;;;-1:-1:-1;13359:27:47;;:32;;13318:74;13317:132;;;;-1:-1:-1;;;;;;13410:20:47;;;;;;:9;:20;;;;;-1:-1:-1;13410:31:47;;13445:3;-1:-1:-1;13410:38:47;13317:132;13309:141;13231:226;-1:-1:-1;;13231:226:47:o;13559:227::-;13670:13;;13655:45;;;;;;13695:1;13655:45;;;;-1:-1:-1;13655:45:47;;;;;;;;-1:-1:-1;;;;;;;;;13670:13:47;;;;13655:39;;:45;;;;;;;;;;;-1:-1:-1;13670:13:47;13655:45;;;5:2:-1;;;;30:1;27;20:12;5:2;13655:45:47;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;13655:45:47;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13655:45:47;;;;-1:-1:-1;;;;;;13714:18:47;;;13710:48;;;13753:5;13746:12;;;;13710:48;13775:4;13768:11;;13559:227;;:::o;728:96:1:-;397:6;;-1:-1:-1;397:6:1;;;;396:7;388:38;;;;;-1:-1:-1;;;;;388:38:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;779:6;:13;;-1:-1:-1;;779:13:1;-1:-1:-1;;;779:13:1;;;807:10;;;813:3;807:10;;;;;;;;;;;;;728:96::o", + "source": "pragma solidity ^0.4.24;\n\nimport \"./ITransferManager.sol\";\nimport \"openzeppelin-solidity/contracts/math/SafeMath.sol\";\n\n/////////////////////\n// Module permissions\n/////////////////////\n// Owner WHITELIST FLAGS\n// changeIssuanceAddress X X\n// changeAllowAllTransfers X X\n// changeAllowAllWhitelistTransfers X X\n// changeAllowAllWhitelistIssuances X X\n// modifyWhitelist X X\n// modifyWhitelistMulti X X\n\n/**\n * @title Transfer Manager module for core transfer validation functionality\n */\ncontract GeneralTransferManager is ITransferManager {\n\n using SafeMath for uint256;\n\n //Address from which issuances come\n address public issuanceAddress = address(0);\n\n //Address which can sign whitelist changes\n address public signingAddress = address(0);\n\n bytes32 public constant WHITELIST = \"WHITELIST\";\n bytes32 public constant FLAGS = \"FLAGS\";\n\n //from and to timestamps that an investor can send / receive tokens respectively\n struct TimeRestriction {\n uint256 fromTime;\n uint256 toTime;\n uint256 expiryTime;\n bool canBuyFromSTO;\n }\n\n // An address can only send / receive tokens once their corresponding uint256 > block.number\n // (unless allowAllTransfers == true or allowAllWhitelistTransfers == true)\n mapping (address => TimeRestriction) public whitelist;\n\n //If true, there are no transfer restrictions, for any addresses\n bool public allowAllTransfers = false;\n //If true, time lock is ignored for transfers (address must still be on whitelist)\n bool public allowAllWhitelistTransfers = false;\n //If true, time lock is ignored for issuances (address must still be on whitelist)\n bool public allowAllWhitelistIssuances = true;\n //If true, time lock is ignored for burn transactions\n bool public allowAllBurnTransfers = false;\n\n // Emit when Issuance address get changed\n event LogChangeIssuanceAddress(address _issuanceAddress);\n // Emit when there is change in the flag variable called allowAllTransfers\n event LogAllowAllTransfers(bool _allowAllTransfers);\n // Emit when there is change in the flag variable called allowAllWhitelistTransfers\n event LogAllowAllWhitelistTransfers(bool _allowAllWhitelistTransfers);\n // Emit when there is change in the flag variable called allowAllWhitelistIssuances\n event LogAllowAllWhitelistIssuances(bool _allowAllWhitelistIssuances);\n // Emit when there is change in the flag variable called allowAllBurnTransfers\n event LogAllowAllBurnTransfers(bool _allowAllBurnTransfers);\n // Emit when there is change in the flag variable called signingAddress\n event LogChangeSigningAddress(address _signingAddress);\n // Emit when investor details get modified related to their whitelisting\n event LogModifyWhitelist(\n address _investor,\n uint256 _dateAdded,\n address _addedBy,\n uint256 _fromTime,\n uint256 _toTime,\n uint256 _expiryTime,\n bool _canBuyFromSTO\n );\n\n /**\n * @notice Constructor\n * @param _securityToken Address of the security token\n * @param _polyAddress Address of the polytoken\n */\n constructor (address _securityToken, address _polyAddress)\n public\n IModule(_securityToken, _polyAddress)\n {\n }\n\n /**\n * @notice This function returns the signature of configure function\n */\n function getInitFunction() public pure returns (bytes4) {\n return bytes4(0);\n }\n\n /**\n * @notice Used to change the Issuance Address\n * @param _issuanceAddress new address for the issuance\n */\n function changeIssuanceAddress(address _issuanceAddress) public withPerm(FLAGS) {\n issuanceAddress = _issuanceAddress;\n emit LogChangeIssuanceAddress(_issuanceAddress);\n }\n\n /**\n * @notice Used to change the Sigining Address\n * @param _signingAddress new address for the signing\n */\n function changeSigningAddress(address _signingAddress) public withPerm(FLAGS) {\n signingAddress = _signingAddress;\n emit LogChangeSigningAddress(_signingAddress);\n }\n\n /**\n * @notice Used to change the flag\n true - It refers there are no transfer restrictions, for any addresses\n false - It refers transfers are restricted for all addresses.\n * @param _allowAllTransfers flag value\n */\n function changeAllowAllTransfers(bool _allowAllTransfers) public withPerm(FLAGS) {\n allowAllTransfers = _allowAllTransfers;\n emit LogAllowAllTransfers(_allowAllTransfers);\n }\n\n /**\n * @notice Used to change the flag\n true - It refers that time lock is ignored for transfers (address must still be on whitelist)\n false - It refers transfers are restricted for all addresses.\n * @param _allowAllWhitelistTransfers flag value\n */\n function changeAllowAllWhitelistTransfers(bool _allowAllWhitelistTransfers) public withPerm(FLAGS) {\n allowAllWhitelistTransfers = _allowAllWhitelistTransfers;\n emit LogAllowAllWhitelistTransfers(_allowAllWhitelistTransfers);\n }\n\n /**\n * @notice Used to change the flag\n true - It refers that time lock is ignored for issuances (address must still be on whitelist)\n false - It refers transfers are restricted for all addresses.\n * @param _allowAllWhitelistIssuances flag value\n */\n function changeAllowAllWhitelistIssuances(bool _allowAllWhitelistIssuances) public withPerm(FLAGS) {\n allowAllWhitelistIssuances = _allowAllWhitelistIssuances;\n emit LogAllowAllWhitelistIssuances(_allowAllWhitelistIssuances);\n }\n\n /**\n * @notice Used to change the flag\n true - It allow to burn the tokens\n false - It deactivate the burning mechanism.\n * @param _allowAllBurnTransfers flag value\n */\n function changeAllowAllBurnTransfers(bool _allowAllBurnTransfers) public withPerm(FLAGS) {\n allowAllBurnTransfers = _allowAllBurnTransfers;\n emit LogAllowAllBurnTransfers(_allowAllBurnTransfers);\n }\n\n /**\n * @notice default implementation of verifyTransfer used by SecurityToken\n * If the transfer request comes from the STO, it only checks that the investor is in the whitelist\n * If the transfer request comes from a token holder, it checks that:\n * a) Both are on the whitelist\n * b) Seller's sale lockup period is over\n * c) Buyer's purchase lockup is over\n */\n function verifyTransfer(address _from, address _to, uint256 /*_amount*/, bool /* _isTransfer */) public returns(Result) {\n if (!paused) {\n if (allowAllTransfers) {\n //All transfers allowed, regardless of whitelist\n return Result.VALID;\n }\n if (allowAllBurnTransfers && (_to == address(0))) {\n return Result.VALID;\n }\n if (allowAllWhitelistTransfers) {\n //Anyone on the whitelist can transfer, regardless of block number\n return (onWhitelist(_to) && onWhitelist(_from)) ? Result.VALID : Result.NA;\n }\n if (allowAllWhitelistIssuances && _from == issuanceAddress) {\n if (!whitelist[_to].canBuyFromSTO && isSTOAttached()) {\n return Result.NA;\n }\n return onWhitelist(_to) ? Result.VALID : Result.NA;\n }\n //Anyone on the whitelist can transfer provided the blocknumber is large enough\n return ((onWhitelist(_from) && whitelist[_from].fromTime <= now) &&\n (onWhitelist(_to) && whitelist[_to].toTime <= now)) ? Result.VALID : Result.NA;\n }\n return Result.NA;\n }\n\n /**\n * @notice adds or removes addresses from the whitelist.\n * @param _investor is the address to whitelist\n * @param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens\n * @param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n * @param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC\n * @param _canBuyFromSTO is used to know whether the investor is restricted investor or not.\n */\n function modifyWhitelist(address _investor, uint256 _fromTime, uint256 _toTime, uint256 _expiryTime, bool _canBuyFromSTO) public withPerm(WHITELIST) {\n //Passing a _time == 0 into this function, is equivalent to removing the _investor from the whitelist\n whitelist[_investor] = TimeRestriction(_fromTime, _toTime, _expiryTime, _canBuyFromSTO);\n emit LogModifyWhitelist(_investor, now, msg.sender, _fromTime, _toTime, _expiryTime, _canBuyFromSTO);\n }\n\n /**\n * @notice adds or removes addresses from the whitelist.\n * @param _investors List of the addresses to whitelist\n * @param _fromTimes An array of the moment when the sale lockup period ends and the investor can freely sell his tokens\n * @param _toTimes An array of the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n * @param _expiryTimes An array of the moment till investors KYC will be validated. After that investor need to do re-KYC\n * @param _canBuyFromSTO An array of boolean values\n */\n function modifyWhitelistMulti(\n address[] _investors,\n uint256[] _fromTimes,\n uint256[] _toTimes,\n uint256[] _expiryTimes,\n bool[] _canBuyFromSTO\n ) public withPerm(WHITELIST) {\n require(_investors.length == _fromTimes.length, \"Mismatched input lengths\");\n require(_fromTimes.length == _toTimes.length, \"Mismatched input lengths\");\n require(_toTimes.length == _expiryTimes.length, \"Mismatched input lengths\");\n require(_canBuyFromSTO.length == _toTimes.length, \"Mismatched input length\");\n for (uint256 i = 0; i < _investors.length; i++) {\n modifyWhitelist(_investors[i], _fromTimes[i], _toTimes[i], _expiryTimes[i], _canBuyFromSTO[i]);\n }\n }\n\n /**\n * @notice adds or removes addresses from the whitelist - can be called by anyone with a valid signature\n * @param _investor is the address to whitelist\n * @param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens\n * @param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n * @param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC\n * @param _canBuyFromSTO is used to know whether the investor is restricted investor or not.\n * @param _validFrom is the time that this signature is valid from\n * @param _validTo is the time that this signature is valid until\n * @param _v issuer signature\n * @param _r issuer signature\n * @param _s issuer signature\n */\n function modifyWhitelistSigned(\n address _investor,\n uint256 _fromTime,\n uint256 _toTime,\n uint256 _expiryTime,\n bool _canBuyFromSTO,\n uint256 _validFrom,\n uint256 _validTo,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) public {\n require(_validFrom <= now, \"ValidFrom is too early\");\n require(_validTo >= now, \"ValidTo is too late\");\n bytes32 hash = keccak256(abi.encodePacked(this, _investor, _fromTime, _toTime, _expiryTime, _canBuyFromSTO, _validFrom, _validTo));\n checkSig(hash, _v, _r, _s);\n //Passing a _time == 0 into this function, is equivalent to removing the _investor from the whitelist\n whitelist[_investor] = TimeRestriction(_fromTime, _toTime, _expiryTime, _canBuyFromSTO);\n emit LogModifyWhitelist(_investor, now, msg.sender, _fromTime, _toTime, _expiryTime, _canBuyFromSTO);\n }\n\n /**\n * @notice used to verify the signature\n */\n function checkSig(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) internal view {\n //Check that the signature is valid\n //sig should be signing - _investor, _fromTime, _toTime & _expiryTime and be signed by the issuer address\n address signer = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash)), _v, _r, _s);\n require(signer == ISecurityToken(securityToken).owner() || signer == signingAddress, \"Incorrect signer\");\n }\n\n /**\n * @notice Return the permissions flag that are associated with general trnasfer manager\n */\n function getPermissions() public view returns(bytes32[]) {\n bytes32[] memory allPermissions = new bytes32[](2);\n allPermissions[0] = WHITELIST;\n allPermissions[1] = FLAGS;\n return allPermissions;\n }\n\n /**\n * @notice Internal function used to check whether the investor is in the whitelist or not\n & also checks whether the KYC of investor get expired or not\n * @param _investor Address of the investor\n */\n function onWhitelist(address _investor) internal view returns(bool) {\n return (((whitelist[_investor].fromTime != 0) || (whitelist[_investor].toTime != 0)) &&\n (whitelist[_investor].expiryTime >= now));\n }\n\n /**\n * @notice Internal function use to know whether the STO is attached or not\n */\n function isSTOAttached() internal view returns(bool) {\n address _sto;\n (, _sto) = ISecurityToken(securityToken).getModule(3, 0);\n if (_sto == address(0))\n return false;\n return true;\n }\n\n}\n", + "sourcePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/TransferManager/GeneralTransferManager.sol", + "ast": { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/TransferManager/GeneralTransferManager.sol", + "exportedSymbols": { + "GeneralTransferManager": [ + 18264 + ] + }, + "id": 18265, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 17587, + "literals": [ + "solidity", + "^", + "0.4", + ".24" + ], + "nodeType": "PragmaDirective", + "src": "0:24:47" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/TransferManager/ITransferManager.sol", + "file": "./ITransferManager.sol", + "id": 17588, + "nodeType": "ImportDirective", + "scope": 18265, + "sourceUnit": 18462, + "src": "26:32:47", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "openzeppelin-solidity/contracts/math/SafeMath.sol", + "file": "openzeppelin-solidity/contracts/math/SafeMath.sol", + "id": 17589, + "nodeType": "ImportDirective", + "scope": 18265, + "sourceUnit": 22697, + "src": "59:59:47", + "symbolAliases": [], + "unitAlias": "" + }, + { + "baseContracts": [ + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 17590, + "name": "ITransferManager", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 18461, + "src": "794:16:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITransferManager_$18461", + "typeString": "contract ITransferManager" + } + }, + "id": 17591, + "nodeType": "InheritanceSpecifier", + "src": "794:16:47" + } + ], + "contractDependencies": [ + 412, + 9596, + 18461 + ], + "contractKind": "contract", + "documentation": "@title Transfer Manager module for core transfer validation functionality", + "fullyImplemented": true, + "id": 18264, + "linearizedBaseContracts": [ + 18264, + 18461, + 412, + 9596 + ], + "name": "GeneralTransferManager", + "nodeType": "ContractDefinition", + "nodes": [ + { + "id": 17594, + "libraryName": { + "contractScope": null, + "id": 17592, + "name": "SafeMath", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 22696, + "src": "824:8:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SafeMath_$22696", + "typeString": "library SafeMath" + } + }, + "nodeType": "UsingForDirective", + "src": "818:27:47", + "typeName": { + "id": 17593, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "837:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "constant": false, + "id": 17599, + "name": "issuanceAddress", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "891:43:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17595, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "891:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17597, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "932:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17596, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "924:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 17598, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "924:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17604, + "name": "signingAddress", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "988:42:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17600, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "988:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17602, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1028:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17601, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1020:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 17603, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1020:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "public" + }, + { + "constant": true, + "id": 17607, + "name": "WHITELIST", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1037:47:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 17605, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1037:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "57484954454c495354", + "id": 17606, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1073:11:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_0af0c3ebe77999ca20698e1ff25f812bf82409a59d21ca15a41f39e0ce9f2500", + "typeString": "literal_string \"WHITELIST\"" + }, + "value": "WHITELIST" + }, + "visibility": "public" + }, + { + "constant": true, + "id": 17610, + "name": "FLAGS", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1090:39:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 17608, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1090:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "464c414753", + "id": 17609, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1122:7:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_343c07b3fb8ec1ffc9ce674026a727b988856209732b2202571e75a0996b3a37", + "typeString": "literal_string \"FLAGS\"" + }, + "value": "FLAGS" + }, + "visibility": "public" + }, + { + "canonicalName": "GeneralTransferManager.TimeRestriction", + "id": 17619, + "members": [ + { + "constant": false, + "id": 17612, + "name": "fromTime", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1254:16:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17611, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1254:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17614, + "name": "toTime", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1280:14:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17613, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1280:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17616, + "name": "expiryTime", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1304:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17615, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1304:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17618, + "name": "canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1332:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17617, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1332:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "TimeRestriction", + "nodeType": "StructDefinition", + "scope": 18264, + "src": "1221:136:47", + "visibility": "public" + }, + { + "constant": false, + "id": 17623, + "name": "whitelist", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1540:53:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction)" + }, + "typeName": { + "id": 17622, + "keyType": { + "id": 17620, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1549:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "1540:36:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction)" + }, + "valueType": { + "contractScope": null, + "id": 17621, + "name": "TimeRestriction", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 17619, + "src": "1560:15:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage_ptr", + "typeString": "struct GeneralTransferManager.TimeRestriction" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 17626, + "name": "allowAllTransfers", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1669:37:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17624, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1669:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 17625, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1701:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17629, + "name": "allowAllWhitelistTransfers", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1799:46:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17627, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1799:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 17628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1840:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17632, + "name": "allowAllWhitelistIssuances", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1938:45:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17630, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1938:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 17631, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1979:4:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17635, + "name": "allowAllBurnTransfers", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "2047:41:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17633, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2047:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 17634, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2083:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "anonymous": false, + "documentation": null, + "id": 17639, + "name": "LogChangeIssuanceAddress", + "nodeType": "EventDefinition", + "parameters": { + "id": 17638, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17637, + "indexed": false, + "name": "_issuanceAddress", + "nodeType": "VariableDeclaration", + "scope": 17639, + "src": "2172:24:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17636, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2172:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2171:26:47" + }, + "src": "2141:57:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17643, + "name": "LogAllowAllTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 17642, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17641, + "indexed": false, + "name": "_allowAllTransfers", + "nodeType": "VariableDeclaration", + "scope": 17643, + "src": "2309:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17640, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2309:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2308:25:47" + }, + "src": "2282:52:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17647, + "name": "LogAllowAllWhitelistTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 17646, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17645, + "indexed": false, + "name": "_allowAllWhitelistTransfers", + "nodeType": "VariableDeclaration", + "scope": 17647, + "src": "2463:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17644, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2463:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2462:34:47" + }, + "src": "2427:70:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17651, + "name": "LogAllowAllWhitelistIssuances", + "nodeType": "EventDefinition", + "parameters": { + "id": 17650, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17649, + "indexed": false, + "name": "_allowAllWhitelistIssuances", + "nodeType": "VariableDeclaration", + "scope": 17651, + "src": "2626:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17648, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2626:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2625:34:47" + }, + "src": "2590:70:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17655, + "name": "LogAllowAllBurnTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 17654, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17653, + "indexed": false, + "name": "_allowAllBurnTransfers", + "nodeType": "VariableDeclaration", + "scope": 17655, + "src": "2779:27:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17652, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2779:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2778:29:47" + }, + "src": "2748:60:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17659, + "name": "LogChangeSigningAddress", + "nodeType": "EventDefinition", + "parameters": { + "id": 17658, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17657, + "indexed": false, + "name": "_signingAddress", + "nodeType": "VariableDeclaration", + "scope": 17659, + "src": "2919:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17656, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2919:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2918:25:47" + }, + "src": "2889:55:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17675, + "name": "LogModifyWhitelist", + "nodeType": "EventDefinition", + "parameters": { + "id": 17674, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17661, + "indexed": false, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3060:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17660, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3060:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17663, + "indexed": false, + "name": "_dateAdded", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3087:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17662, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3087:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17665, + "indexed": false, + "name": "_addedBy", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3115:16:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17664, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3115:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17667, + "indexed": false, + "name": "_fromTime", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3141:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17666, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3141:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17669, + "indexed": false, + "name": "_toTime", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3168:15:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17668, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3168:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17671, + "indexed": false, + "name": "_expiryTime", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3193:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17670, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3193:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17673, + "indexed": false, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3222:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17672, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3222:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3050:197:47" + }, + "src": "3026:222:47" + }, + { + "body": { + "id": 17686, + "nodeType": "Block", + "src": "3524:7:47", + "statements": [] + }, + "documentation": "@notice Constructor\n@param _securityToken Address of the security token\n@param _polyAddress Address of the polytoken", + "id": 17687, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17682, + "name": "_securityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17677, + "src": "3490:14:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 17683, + "name": "_polyAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17679, + "src": "3506:12:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 17684, + "modifierName": { + "argumentTypes": null, + "id": 17681, + "name": "IModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9596, + "src": "3482:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModule_$9596_$", + "typeString": "type(contract IModule)" + } + }, + "nodeType": "ModifierInvocation", + "src": "3482:37:47" + } + ], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17680, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17677, + "name": "_securityToken", + "nodeType": "VariableDeclaration", + "scope": 17687, + "src": "3421:22:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17676, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3421:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17679, + "name": "_polyAddress", + "nodeType": "VariableDeclaration", + "scope": 17687, + "src": "3445:20:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17678, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3445:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3420:46:47" + }, + "payable": false, + "returnParameters": { + "id": 17685, + "nodeType": "ParameterList", + "parameters": [], + "src": "3524:0:47" + }, + "scope": 18264, + "src": "3408:123:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17696, + "nodeType": "Block", + "src": "3682:33:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17693, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3706:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17692, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3699:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 17694, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3699:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "functionReturnParameters": 17691, + "id": 17695, + "nodeType": "Return", + "src": "3692:16:47" + } + ] + }, + "documentation": "@notice This function returns the signature of configure function", + "id": 17697, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getInitFunction", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17688, + "nodeType": "ParameterList", + "parameters": [], + "src": "3650:2:47" + }, + "payable": false, + "returnParameters": { + "id": 17691, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17690, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17697, + "src": "3674:6:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 17689, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "3674:6:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3673:8:47" + }, + "scope": 18264, + "src": "3626:89:47", + "stateMutability": "pure", + "superFunction": 9475, + "visibility": "public" + }, + { + "body": { + "id": 17713, + "nodeType": "Block", + "src": "3928:108:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17707, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17705, + "name": "issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17599, + "src": "3938:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17706, + "name": "_issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17699, + "src": "3956:16:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3938:34:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 17708, + "nodeType": "ExpressionStatement", + "src": "3938:34:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17710, + "name": "_issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17699, + "src": "4012:16:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17709, + "name": "LogChangeIssuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17639, + "src": "3987:24:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 17711, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3987:42:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17712, + "nodeType": "EmitStatement", + "src": "3982:47:47" + } + ] + }, + "documentation": "@notice Used to change the Issuance Address\n@param _issuanceAddress new address for the issuance", + "id": 17714, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17702, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "3921:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17703, + "modifierName": { + "argumentTypes": null, + "id": 17701, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "3912:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "3912:15:47" + } + ], + "name": "changeIssuanceAddress", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17700, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17699, + "name": "_issuanceAddress", + "nodeType": "VariableDeclaration", + "scope": 17714, + "src": "3879:24:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17698, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3879:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3878:26:47" + }, + "payable": false, + "returnParameters": { + "id": 17704, + "nodeType": "ParameterList", + "parameters": [], + "src": "3928:0:47" + }, + "scope": 18264, + "src": "3848:188:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17730, + "nodeType": "Block", + "src": "4245:104:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17722, + "name": "signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17604, + "src": "4255:14:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17723, + "name": "_signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17716, + "src": "4272:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4255:32:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 17725, + "nodeType": "ExpressionStatement", + "src": "4255:32:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17727, + "name": "_signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17716, + "src": "4326:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17726, + "name": "LogChangeSigningAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17659, + "src": "4302:23:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 17728, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4302:40:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17729, + "nodeType": "EmitStatement", + "src": "4297:45:47" + } + ] + }, + "documentation": "@notice Used to change the Sigining Address\n@param _signingAddress new address for the signing", + "id": 17731, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17719, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "4238:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17720, + "modifierName": { + "argumentTypes": null, + "id": 17718, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "4229:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "4229:15:47" + } + ], + "name": "changeSigningAddress", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17717, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17716, + "name": "_signingAddress", + "nodeType": "VariableDeclaration", + "scope": 17731, + "src": "4197:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17715, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4197:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4196:25:47" + }, + "payable": false, + "returnParameters": { + "id": 17721, + "nodeType": "ParameterList", + "parameters": [], + "src": "4245:0:47" + }, + "scope": 18264, + "src": "4167:182:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17747, + "nodeType": "Block", + "src": "4692:110:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17741, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17739, + "name": "allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17626, + "src": "4702:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17740, + "name": "_allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17733, + "src": "4722:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4702:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17742, + "nodeType": "ExpressionStatement", + "src": "4702:38:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17744, + "name": "_allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17733, + "src": "4776:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17743, + "name": "LogAllowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17643, + "src": "4755:20:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4755:40:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17746, + "nodeType": "EmitStatement", + "src": "4750:45:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It refers there are no transfer restrictions, for any addresses\nfalse - It refers transfers are restricted for all addresses.\n@param _allowAllTransfers flag value", + "id": 17748, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17736, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "4685:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17737, + "modifierName": { + "argumentTypes": null, + "id": 17735, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "4676:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "4676:15:47" + } + ], + "name": "changeAllowAllTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17734, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17733, + "name": "_allowAllTransfers", + "nodeType": "VariableDeclaration", + "scope": 17748, + "src": "4644:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17732, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4644:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4643:25:47" + }, + "payable": false, + "returnParameters": { + "id": 17738, + "nodeType": "ParameterList", + "parameters": [], + "src": "4692:0:47" + }, + "scope": 18264, + "src": "4611:191:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17764, + "nodeType": "Block", + "src": "5195:146:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17758, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17756, + "name": "allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17629, + "src": "5205:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17757, + "name": "_allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17750, + "src": "5234:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5205:56:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17759, + "nodeType": "ExpressionStatement", + "src": "5205:56:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17761, + "name": "_allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17750, + "src": "5306:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17760, + "name": "LogAllowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17647, + "src": "5276:29:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17762, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5276:58:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17763, + "nodeType": "EmitStatement", + "src": "5271:63:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It refers that time lock is ignored for transfers (address must still be on whitelist)\nfalse - It refers transfers are restricted for all addresses.\n@param _allowAllWhitelistTransfers flag value", + "id": 17765, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17753, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "5188:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17754, + "modifierName": { + "argumentTypes": null, + "id": 17752, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "5179:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5179:15:47" + } + ], + "name": "changeAllowAllWhitelistTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17751, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17750, + "name": "_allowAllWhitelistTransfers", + "nodeType": "VariableDeclaration", + "scope": 17765, + "src": "5138:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17749, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5138:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5137:34:47" + }, + "payable": false, + "returnParameters": { + "id": 17755, + "nodeType": "ParameterList", + "parameters": [], + "src": "5195:0:47" + }, + "scope": 18264, + "src": "5096:245:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17781, + "nodeType": "Block", + "src": "5734:146:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17775, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17773, + "name": "allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17632, + "src": "5744:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17774, + "name": "_allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17767, + "src": "5773:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5744:56:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17776, + "nodeType": "ExpressionStatement", + "src": "5744:56:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17778, + "name": "_allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17767, + "src": "5845:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17777, + "name": "LogAllowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17651, + "src": "5815:29:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17779, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5815:58:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17780, + "nodeType": "EmitStatement", + "src": "5810:63:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It refers that time lock is ignored for issuances (address must still be on whitelist)\nfalse - It refers transfers are restricted for all addresses.\n@param _allowAllWhitelistIssuances flag value", + "id": 17782, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17770, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "5727:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17771, + "modifierName": { + "argumentTypes": null, + "id": 17769, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "5718:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5718:15:47" + } + ], + "name": "changeAllowAllWhitelistIssuances", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17768, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17767, + "name": "_allowAllWhitelistIssuances", + "nodeType": "VariableDeclaration", + "scope": 17782, + "src": "5677:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17766, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5677:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5676:34:47" + }, + "payable": false, + "returnParameters": { + "id": 17772, + "nodeType": "ParameterList", + "parameters": [], + "src": "5734:0:47" + }, + "scope": 18264, + "src": "5635:245:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17798, + "nodeType": "Block", + "src": "6182:126:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17792, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17790, + "name": "allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17635, + "src": "6192:21:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17791, + "name": "_allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17784, + "src": "6216:22:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "6192:46:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17793, + "nodeType": "ExpressionStatement", + "src": "6192:46:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17795, + "name": "_allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17784, + "src": "6278:22:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17794, + "name": "LogAllowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17655, + "src": "6253:24:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17796, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6253:48:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17797, + "nodeType": "EmitStatement", + "src": "6248:53:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It allow to burn the tokens\nfalse - It deactivate the burning mechanism.\n@param _allowAllBurnTransfers flag value", + "id": 17799, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17787, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "6175:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17788, + "modifierName": { + "argumentTypes": null, + "id": 17786, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "6166:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "6166:15:47" + } + ], + "name": "changeAllowAllBurnTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17785, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17784, + "name": "_allowAllBurnTransfers", + "nodeType": "VariableDeclaration", + "scope": 17799, + "src": "6130:27:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17783, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "6130:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6129:29:47" + }, + "payable": false, + "returnParameters": { + "id": 17789, + "nodeType": "ParameterList", + "parameters": [], + "src": "6182:0:47" + }, + "scope": 18264, + "src": "6093:215:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17914, + "nodeType": "Block", + "src": "6823:1121:47", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 17813, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "6837:7:47", + "subExpression": { + "argumentTypes": null, + "id": 17812, + "name": "paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 364, + "src": "6838:6:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17910, + "nodeType": "IfStatement", + "src": "6833:1079:47", + "trueBody": { + "id": 17909, + "nodeType": "Block", + "src": "6846:1066:47", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 17814, + "name": "allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17626, + "src": "6864:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17819, + "nodeType": "IfStatement", + "src": "6860:140:47", + "trueBody": { + "id": 17818, + "nodeType": "Block", + "src": "6883:117:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17815, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "6973:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17816, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "6973:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17817, + "nodeType": "Return", + "src": "6966:19:47" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17827, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17820, + "name": "allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17635, + "src": "7017:21:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 17825, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17821, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7043:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17823, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7058:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17822, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "7050:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 17824, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7050:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "7043:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17826, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7042:19:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7017:44:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17832, + "nodeType": "IfStatement", + "src": "7013:102:47", + "trueBody": { + "id": 17831, + "nodeType": "Block", + "src": "7063:52:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17828, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7088:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17829, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7088:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17830, + "nodeType": "Return", + "src": "7081:19:47" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "id": 17833, + "name": "allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17629, + "src": "7132:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17849, + "nodeType": "IfStatement", + "src": "7128:222:47", + "trueBody": { + "id": 17848, + "nodeType": "Block", + "src": "7160:190:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17840, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17835, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7281:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17834, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7269:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17836, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7269:16:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17838, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7301:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17837, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7289:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17839, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7289:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7269:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17841, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7268:40:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17844, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7326:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17845, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7326:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "id": 17846, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "7268:67:47", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17842, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7311:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17843, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7311:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17847, + "nodeType": "Return", + "src": "7261:74:47" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17854, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17850, + "name": "allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17632, + "src": "7367:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 17853, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17851, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7397:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 17852, + "name": "issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17599, + "src": "7406:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "7397:24:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7367:54:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17878, + "nodeType": "IfStatement", + "src": "7363:271:47", + "trueBody": { + "id": 17877, + "nodeType": "Block", + "src": "7423:211:47", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17859, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "7445:29:47", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17855, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "7446:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17857, + "indexExpression": { + "argumentTypes": null, + "id": 17856, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7456:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7446:14:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17858, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "canBuyFromSTO", + "nodeType": "MemberAccess", + "referencedDeclaration": 17618, + "src": "7446:28:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 17860, + "name": "isSTOAttached", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18263, + "src": "7478:13:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_bool_$", + "typeString": "function () view returns (bool)" + } + }, + "id": 17861, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7478:15:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7445:48:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17867, + "nodeType": "IfStatement", + "src": "7441:111:47", + "trueBody": { + "id": 17866, + "nodeType": "Block", + "src": "7495:57:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17863, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7524:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17864, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7524:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17865, + "nodeType": "Return", + "src": "7517:16:47" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17869, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7588:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17868, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7576:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17870, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7576:16:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17873, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7610:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17874, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7610:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "id": 17875, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "7576:43:47", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17871, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7595:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17872, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7595:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17876, + "nodeType": "Return", + "src": "7569:50:47" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17901, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17888, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17880, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7760:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17879, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7748:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17881, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7748:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17887, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17882, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "7770:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17884, + "indexExpression": { + "argumentTypes": null, + "id": 17883, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7780:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7770:16:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17885, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "fromTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17612, + "src": "7770:25:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 17886, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "7799:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7770:32:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7748:54:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17889, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7747:56:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17899, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17891, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7836:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17890, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7824:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17892, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7824:16:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17898, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17893, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "7844:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17895, + "indexExpression": { + "argumentTypes": null, + "id": 17894, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7854:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7844:14:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17896, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "toTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17614, + "src": "7844:21:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 17897, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "7869:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7844:28:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7824:48:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17900, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7823:50:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7747:126:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17902, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7746:128:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17905, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7892:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17906, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7892:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "id": 17907, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "7746:155:47", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17903, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7877:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17904, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7877:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17908, + "nodeType": "Return", + "src": "7739:162:47" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17911, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7928:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17912, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7928:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17913, + "nodeType": "Return", + "src": "7921:16:47" + } + ] + }, + "documentation": "@notice default implementation of verifyTransfer used by SecurityToken\nIf the transfer request comes from the STO, it only checks that the investor is in the whitelist\nIf the transfer request comes from a token holder, it checks that:\na) Both are on the whitelist\nb) Seller's sale lockup period is over\nc) Buyer's purchase lockup is over", + "id": 17915, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "verifyTransfer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17808, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17801, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6727:13:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17800, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6727:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17803, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6742:11:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17802, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6742:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17805, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6755:7:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17804, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6755:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17807, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6776:4:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17806, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "6776:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6726:73:47" + }, + "payable": false, + "returnParameters": { + "id": 17811, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17810, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6815:6:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + }, + "typeName": { + "contractScope": null, + "id": 17809, + "name": "Result", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 18425, + "src": "6815:6:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6814:8:47" + }, + "scope": 18264, + "src": "6703:1241:47", + "stateMutability": "nonpayable", + "superFunction": 18438, + "visibility": "public" + }, + { + "body": { + "id": 17953, + "nodeType": "Block", + "src": "8678:324:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17940, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17931, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "8798:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17933, + "indexExpression": { + "argumentTypes": null, + "id": 17932, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17917, + "src": "8808:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "8798:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17935, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17919, + "src": "8837:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17936, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17921, + "src": "8848:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17937, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17923, + "src": "8857:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17938, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17925, + "src": "8870:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17934, + "name": "TimeRestriction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17619, + "src": "8821:15:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_TimeRestriction_$17619_storage_ptr_$", + "typeString": "type(struct GeneralTransferManager.TimeRestriction storage pointer)" + } + }, + "id": 17939, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8821:64:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_memory", + "typeString": "struct GeneralTransferManager.TimeRestriction memory" + } + }, + "src": "8798:87:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17941, + "nodeType": "ExpressionStatement", + "src": "8798:87:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17943, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17917, + "src": "8919:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 17944, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "8930:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17945, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23249, + "src": "8935:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 17946, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "8935:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 17947, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17919, + "src": "8947:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17948, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17921, + "src": "8958:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17949, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17923, + "src": "8967:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17950, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17925, + "src": "8980:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17942, + "name": "LogModifyWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17675, + "src": "8900:18:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (address,uint256,address,uint256,uint256,uint256,bool)" + } + }, + "id": 17951, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8900:95:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17952, + "nodeType": "EmitStatement", + "src": "8895:100:47" + } + ] + }, + "documentation": "@notice adds or removes addresses from the whitelist.\n@param _investor is the address to whitelist\n@param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens\n@param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n@param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC\n@param _canBuyFromSTO is used to know whether the investor is restricted investor or not.", + "id": 17954, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17928, + "name": "WHITELIST", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17607, + "src": "8667:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17929, + "modifierName": { + "argumentTypes": null, + "id": 17927, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "8658:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "8658:19:47" + } + ], + "name": "modifyWhitelist", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17926, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17917, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8554:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17916, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8554:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17919, + "name": "_fromTime", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8573:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17918, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8573:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17921, + "name": "_toTime", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8592:15:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17920, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8592:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17923, + "name": "_expiryTime", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8609:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17922, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8609:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17925, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8630:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17924, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "8630:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "8553:97:47" + }, + "payable": false, + "returnParameters": { + "id": 17930, + "nodeType": "ParameterList", + "parameters": [], + "src": "8678:0:47" + }, + "scope": 18264, + "src": "8529:473:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 18042, + "nodeType": "Block", + "src": "9798:522:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17980, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17976, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17957, + "src": "9816:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 17977, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9816:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17978, + "name": "_fromTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17960, + "src": "9837:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17979, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9837:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9816:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e67746873", + "id": 17981, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9856:26:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + }, + "value": "Mismatched input lengths" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + } + ], + "id": 17975, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "9808:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 17982, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9808:75:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17983, + "nodeType": "ExpressionStatement", + "src": "9808:75:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17989, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17985, + "name": "_fromTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17960, + "src": "9901:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17986, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9901:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17987, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "9922:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17988, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9922:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9901:36:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e67746873", + "id": 17990, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9939:26:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + }, + "value": "Mismatched input lengths" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + } + ], + "id": 17984, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "9893:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 17991, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9893:73:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17992, + "nodeType": "ExpressionStatement", + "src": "9893:73:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17994, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "9984:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17995, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9984:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17996, + "name": "_expiryTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17966, + "src": "10003:12:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17997, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10003:19:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9984:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e67746873", + "id": 17999, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10024:26:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + }, + "value": "Mismatched input lengths" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + } + ], + "id": 17993, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "9976:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18000, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9976:75:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18001, + "nodeType": "ExpressionStatement", + "src": "9976:75:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18007, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18003, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17969, + "src": "10069:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_memory_ptr", + "typeString": "bool[] memory" + } + }, + "id": 18004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10069:21:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18005, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "10094:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18006, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10094:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10069:40:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e677468", + "id": 18008, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10111:25:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_105cd25b3fa111d79edd195a9110213618d4a0b70897083c4c45e06854cf081f", + "typeString": "literal_string \"Mismatched input length\"" + }, + "value": "Mismatched input length" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_105cd25b3fa111d79edd195a9110213618d4a0b70897083c4c45e06854cf081f", + "typeString": "literal_string \"Mismatched input length\"" + } + ], + "id": 18002, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "10061:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18009, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10061:76:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18010, + "nodeType": "ExpressionStatement", + "src": "10061:76:47" + }, + { + "body": { + "id": 18040, + "nodeType": "Block", + "src": "10195:119:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18023, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17957, + "src": "10225:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 18025, + "indexExpression": { + "argumentTypes": null, + "id": 18024, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10236:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10225:13:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18026, + "name": "_fromTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17960, + "src": "10240:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18028, + "indexExpression": { + "argumentTypes": null, + "id": 18027, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10251:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10240:13:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18029, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "10255:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18031, + "indexExpression": { + "argumentTypes": null, + "id": 18030, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10264:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10255:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18032, + "name": "_expiryTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17966, + "src": "10268:12:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18034, + "indexExpression": { + "argumentTypes": null, + "id": 18033, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10281:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10268:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18035, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17969, + "src": "10285:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_memory_ptr", + "typeString": "bool[] memory" + } + }, + "id": 18037, + "indexExpression": { + "argumentTypes": null, + "id": 18036, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10300:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10285:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 18022, + "name": "modifyWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17954, + "src": "10209:15:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (address,uint256,uint256,uint256,bool)" + } + }, + "id": 18038, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10209:94:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18039, + "nodeType": "ExpressionStatement", + "src": "10209:94:47" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18018, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18015, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10167:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18016, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17957, + "src": "10171:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 18017, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10171:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10167:21:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 18041, + "initializationExpression": { + "assignments": [ + 18012 + ], + "declarations": [ + { + "constant": false, + "id": 18012, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "10152:9:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18011, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10152:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18014, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 18013, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10164:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "10152:13:47" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 18020, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "10190:3:47", + "subExpression": { + "argumentTypes": null, + "id": 18019, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10190:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 18021, + "nodeType": "ExpressionStatement", + "src": "10190:3:47" + }, + "nodeType": "ForStatement", + "src": "10147:167:47" + } + ] + }, + "documentation": "@notice adds or removes addresses from the whitelist.\n@param _investors List of the addresses to whitelist\n@param _fromTimes An array of the moment when the sale lockup period ends and the investor can freely sell his tokens\n@param _toTimes An array of the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n@param _expiryTimes An array of the moment till investors KYC will be validated. After that investor need to do re-KYC\n@param _canBuyFromSTO An array of boolean values", + "id": 18043, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17972, + "name": "WHITELIST", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17607, + "src": "9787:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17973, + "modifierName": { + "argumentTypes": null, + "id": 17971, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "9778:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "9778:19:47" + } + ], + "name": "modifyWhitelistMulti", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17970, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17957, + "name": "_investors", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9623:20:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 17955, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9623:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 17956, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9623:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17960, + "name": "_fromTimes", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9653:20:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 17958, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9653:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 17959, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9653:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17963, + "name": "_toTimes", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9683:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 17961, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9683:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 17962, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9683:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17966, + "name": "_expiryTimes", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9711:22:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 17964, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9711:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 17965, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9711:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17969, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9743:21:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_memory_ptr", + "typeString": "bool[]" + }, + "typeName": { + "baseType": { + "id": 17967, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "9743:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17968, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9743:6:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_storage_ptr", + "typeString": "bool[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9613:157:47" + }, + "payable": false, + "returnParameters": { + "id": 17974, + "nodeType": "ParameterList", + "parameters": [], + "src": "9798:0:47" + }, + "scope": 18264, + "src": "9584:736:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 18125, + "nodeType": "Block", + "src": "11484:619:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18069, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18067, + "name": "_validFrom", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18055, + "src": "11502:10:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 18068, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "11516:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11502:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "56616c696446726f6d20697320746f6f206561726c79", + "id": 18070, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11521:24:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_99e48cd3a89cd958b606f09b46fee13c6f02a8c1cabd819bdc259be60f8be245", + "typeString": "literal_string \"ValidFrom is too early\"" + }, + "value": "ValidFrom is too early" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_99e48cd3a89cd958b606f09b46fee13c6f02a8c1cabd819bdc259be60f8be245", + "typeString": "literal_string \"ValidFrom is too early\"" + } + ], + "id": 18066, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "11494:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18071, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11494:52:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18072, + "nodeType": "ExpressionStatement", + "src": "11494:52:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18076, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18074, + "name": "_validTo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18057, + "src": "11564:8:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 18075, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "11576:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11564:15:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "56616c6964546f20697320746f6f206c617465", + "id": 18077, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11581:21:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_32b35358d9cb029ce5f1705ced20cd49735d5c5348949ad9326e100596c13439", + "typeString": "literal_string \"ValidTo is too late\"" + }, + "value": "ValidTo is too late" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_32b35358d9cb029ce5f1705ced20cd49735d5c5348949ad9326e100596c13439", + "typeString": "literal_string \"ValidTo is too late\"" + } + ], + "id": 18073, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "11556:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18078, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11556:47:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18079, + "nodeType": "ExpressionStatement", + "src": "11556:47:47" + }, + { + "assignments": [ + 18081 + ], + "declarations": [ + { + "constant": false, + "id": 18081, + "name": "hash", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11613:12:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18080, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "11613:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18095, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18085, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23406, + "src": "11655:4:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_GeneralTransferManager_$18264", + "typeString": "contract GeneralTransferManager" + } + }, + { + "argumentTypes": null, + "id": 18086, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18045, + "src": "11661:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 18087, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18047, + "src": "11672:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18088, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18049, + "src": "11683:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18089, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18051, + "src": "11692:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18090, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18053, + "src": "11705:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "id": 18091, + "name": "_validFrom", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18055, + "src": "11721:10:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18092, + "name": "_validTo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18057, + "src": "11733:8:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_GeneralTransferManager_$18264", + "typeString": "contract GeneralTransferManager" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 18083, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23236, + "src": "11638:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 18084, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11638:16:47", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 18093, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11638:104:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 18082, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23243, + "src": "11628:9:47", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 18094, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11628:115:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11613:130:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18097, + "name": "hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18081, + "src": "11762:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18098, + "name": "_v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18059, + "src": "11768:2:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "id": 18099, + "name": "_r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18061, + "src": "11772:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18100, + "name": "_s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18063, + "src": "11776:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 18096, + "name": "checkSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18168, + "src": "11753:8:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_uint8_$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,uint8,bytes32,bytes32) view" + } + }, + "id": 18101, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11753:26:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18102, + "nodeType": "ExpressionStatement", + "src": "11753:26:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18112, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18103, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "11899:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18105, + "indexExpression": { + "argumentTypes": null, + "id": 18104, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18045, + "src": "11909:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "11899:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18107, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18047, + "src": "11938:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18108, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18049, + "src": "11949:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18109, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18051, + "src": "11958:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18110, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18053, + "src": "11971:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 18106, + "name": "TimeRestriction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17619, + "src": "11922:15:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_TimeRestriction_$17619_storage_ptr_$", + "typeString": "type(struct GeneralTransferManager.TimeRestriction storage pointer)" + } + }, + "id": 18111, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11922:64:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_memory", + "typeString": "struct GeneralTransferManager.TimeRestriction memory" + } + }, + "src": "11899:87:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18113, + "nodeType": "ExpressionStatement", + "src": "11899:87:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18115, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18045, + "src": "12020:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 18116, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "12031:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18117, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23249, + "src": "12036:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 18118, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12036:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 18119, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18047, + "src": "12048:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18120, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18049, + "src": "12059:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18121, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18051, + "src": "12068:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18122, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18053, + "src": "12081:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 18114, + "name": "LogModifyWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17675, + "src": "12001:18:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (address,uint256,address,uint256,uint256,uint256,bool)" + } + }, + "id": 18123, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12001:95:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18124, + "nodeType": "EmitStatement", + "src": "11996:100:47" + } + ] + }, + "documentation": "@notice adds or removes addresses from the whitelist - can be called by anyone with a valid signature\n@param _investor is the address to whitelist\n@param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens\n@param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n@param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC\n@param _canBuyFromSTO is used to know whether the investor is restricted investor or not.\n@param _validFrom is the time that this signature is valid from\n@param _validTo is the time that this signature is valid until\n@param _v issuer signature\n@param _r issuer signature\n@param _s issuer signature", + "id": 18126, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "modifyWhitelistSigned", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18064, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18045, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11231:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18044, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "11231:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18047, + "name": "_fromTime", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11258:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18046, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11258:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18049, + "name": "_toTime", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11285:15:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18048, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11285:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18051, + "name": "_expiryTime", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11310:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18050, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11310:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18053, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11339:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 18052, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "11339:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18055, + "name": "_validFrom", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11368:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18054, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11368:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18057, + "name": "_validTo", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11396:16:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18056, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11396:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18059, + "name": "_v", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11422:8:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 18058, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "11422:5:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18061, + "name": "_r", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11440:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18060, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "11440:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18063, + "name": "_s", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11460:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18062, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "11460:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "11221:255:47" + }, + "payable": false, + "returnParameters": { + "id": 18065, + "nodeType": "ParameterList", + "parameters": [], + "src": "11484:0:47" + }, + "scope": 18264, + "src": "11191:912:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 18167, + "nodeType": "Block", + "src": "12250:399:47", + "statements": [ + { + "assignments": [ + 18138 + ], + "declarations": [ + { + "constant": false, + "id": 18138, + "name": "signer", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12418:14:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18137, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "12418:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18151, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "19457468657265756d205369676e6564204d6573736167653a0a3332", + "id": 18143, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12472:34:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73", + "typeString": "literal_string \"\u0019Ethereum Signed Message:\n32\"" + }, + "value": "\u0019Ethereum Signed Message:\n32" + }, + { + "argumentTypes": null, + "id": 18144, + "name": "_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18128, + "src": "12508:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73", + "typeString": "literal_string \"\u0019Ethereum Signed Message:\n32\"" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "argumentTypes": null, + "id": 18141, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23236, + "src": "12455:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 18142, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12455:16:47", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 18145, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12455:59:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 18140, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23243, + "src": "12445:9:47", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 18146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12445:70:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18147, + "name": "_v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18130, + "src": "12517:2:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "id": 18148, + "name": "_r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18132, + "src": "12521:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18149, + "name": "_s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18134, + "src": "12525:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 18139, + "name": "ecrecover", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23241, + "src": "12435:9:47", + "typeDescriptions": { + "typeIdentifier": "t_function_ecrecover_pure$_t_bytes32_$_t_uint8_$_t_bytes32_$_t_bytes32_$returns$_t_address_$", + "typeString": "function (bytes32,uint8,bytes32,bytes32) pure returns (address)" + } + }, + "id": 18150, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12435:93:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12418:110:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 18163, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 18159, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18153, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18138, + "src": "12546:6:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18155, + "name": "securityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9442, + "src": "12571:13:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 18154, + "name": "ISecurityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10038, + "src": "12556:14:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ISecurityToken_$10038_$", + "typeString": "type(contract ISecurityToken)" + } + }, + "id": 18156, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12556:29:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ISecurityToken_$10038", + "typeString": "contract ISecurityToken" + } + }, + "id": 18157, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "owner", + "nodeType": "MemberAccess", + "referencedDeclaration": 22700, + "src": "12556:35:47", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_address_$", + "typeString": "function () view external returns (address)" + } + }, + "id": 18158, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12556:37:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "12546:47:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 18162, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18160, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18138, + "src": "12597:6:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 18161, + "name": "signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17604, + "src": "12607:14:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "12597:24:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "12546:75:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e636f7272656374207369676e6572", + "id": 18164, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12623:18:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f959bac4fcb8350e440bda9ef2e133685bbcca7e96b8c2ce30bcb87b7e733c10", + "typeString": "literal_string \"Incorrect signer\"" + }, + "value": "Incorrect signer" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f959bac4fcb8350e440bda9ef2e133685bbcca7e96b8c2ce30bcb87b7e733c10", + "typeString": "literal_string \"Incorrect signer\"" + } + ], + "id": 18152, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "12538:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18165, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12538:104:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18166, + "nodeType": "ExpressionStatement", + "src": "12538:104:47" + } + ] + }, + "documentation": "@notice used to verify the signature", + "id": 18168, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "checkSig", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18135, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18128, + "name": "_hash", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12187:13:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18127, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12187:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18130, + "name": "_v", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12202:8:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 18129, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "12202:5:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18132, + "name": "_r", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12212:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18131, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12212:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18134, + "name": "_s", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12224:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18133, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12224:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12186:49:47" + }, + "payable": false, + "returnParameters": { + "id": 18136, + "nodeType": "ParameterList", + "parameters": [], + "src": "12250:0:47" + }, + "scope": 18264, + "src": "12169:480:47", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 18198, + "nodeType": "Block", + "src": "12821:172:47", + "statements": [ + { + "assignments": [ + 18177 + ], + "declarations": [ + { + "constant": false, + "id": 18177, + "name": "allPermissions", + "nodeType": "VariableDeclaration", + "scope": 18199, + "src": "12831:31:47", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 18175, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12831:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18176, + "length": null, + "nodeType": "ArrayTypeName", + "src": "12831:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18183, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "32", + "id": 18181, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12879:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "id": 18180, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "12865:13:47", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_bytes32_$dyn_memory_$", + "typeString": "function (uint256) pure returns (bytes32[] memory)" + }, + "typeName": { + "baseType": { + "id": 18178, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12869:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18179, + "length": null, + "nodeType": "ArrayTypeName", + "src": "12869:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + } + }, + "id": 18182, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12865:16:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory", + "typeString": "bytes32[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12831:50:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18188, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18184, + "name": "allPermissions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18177, + "src": "12891:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 18186, + "indexExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 18185, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12906:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "12891:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 18187, + "name": "WHITELIST", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17607, + "src": "12911:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "12891:29:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18189, + "nodeType": "ExpressionStatement", + "src": "12891:29:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18194, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18190, + "name": "allPermissions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18177, + "src": "12930:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 18192, + "indexExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 18191, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12945:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "12930:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 18193, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "12950:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "12930:25:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18195, + "nodeType": "ExpressionStatement", + "src": "12930:25:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18196, + "name": "allPermissions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18177, + "src": "12972:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "functionReturnParameters": 18173, + "id": 18197, + "nodeType": "Return", + "src": "12965:21:47" + } + ] + }, + "documentation": "@notice Return the permissions flag that are associated with general trnasfer manager", + "id": 18199, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getPermissions", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18169, + "nodeType": "ParameterList", + "parameters": [], + "src": "12787:2:47" + }, + "payable": false, + "returnParameters": { + "id": 18173, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18172, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 18199, + "src": "12810:9:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 18170, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12810:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18171, + "length": null, + "nodeType": "ArrayTypeName", + "src": "12810:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12809:11:47" + }, + "scope": 18264, + "src": "12764:229:47", + "stateMutability": "view", + "superFunction": 9568, + "visibility": "public" + }, + { + "body": { + "id": 18232, + "nodeType": "Block", + "src": "13299:158:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 18229, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 18220, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18211, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18206, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "13319:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18208, + "indexExpression": { + "argumentTypes": null, + "id": 18207, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18201, + "src": "13329:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13319:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18209, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "fromTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17612, + "src": "13319:29:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 18210, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13352:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13319:34:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18212, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13318:36:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18218, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18213, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "13359:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18215, + "indexExpression": { + "argumentTypes": null, + "id": 18214, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18201, + "src": "13369:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13359:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18216, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "toTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17614, + "src": "13359:27:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 18217, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13390:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13359:32:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18219, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13358:34:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13318:74:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18221, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13317:76:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18227, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18222, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "13410:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18224, + "indexExpression": { + "argumentTypes": null, + "id": 18223, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18201, + "src": "13420:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13410:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18225, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "expiryTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17616, + "src": "13410:31:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 18226, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "13445:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13410:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18228, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13409:40:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13317:132:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18230, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13316:134:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 18205, + "id": 18231, + "nodeType": "Return", + "src": "13309:141:47" + } + ] + }, + "documentation": "@notice Internal function used to check whether the investor is in the whitelist or not\n& also checks whether the KYC of investor get expired or not\n@param _investor Address of the investor", + "id": 18233, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "onWhitelist", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18202, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18201, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 18233, + "src": "13252:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18200, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13252:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13251:19:47" + }, + "payable": false, + "returnParameters": { + "id": 18205, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18204, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 18233, + "src": "13293:4:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 18203, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "13293:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13292:6:47" + }, + "scope": 18264, + "src": "13231:226:47", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 18262, + "nodeType": "Block", + "src": "13612:174:47", + "statements": [ + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 18239, + "name": "_sto", + "nodeType": "VariableDeclaration", + "scope": 18263, + "src": "13622:12:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18238, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13622:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18240, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "13622:12:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18250, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "components": [ + null, + { + "argumentTypes": null, + "id": 18241, + "name": "_sto", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18239, + "src": "13647:4:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 18242, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "13644:8:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$_t_address_$", + "typeString": "tuple(,address)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "33", + "id": 18247, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13695:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + { + "argumentTypes": null, + "hexValue": "30", + "id": 18248, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13698:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18244, + "name": "securityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9442, + "src": "13670:13:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 18243, + "name": "ISecurityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10038, + "src": "13655:14:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ISecurityToken_$10038_$", + "typeString": "type(contract ISecurityToken)" + } + }, + "id": 18245, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13655:29:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ISecurityToken_$10038", + "typeString": "contract ISecurityToken" + } + }, + "id": 18246, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getModule", + "nodeType": "MemberAccess", + "referencedDeclaration": 10000, + "src": "13655:39:47", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_uint8_$_t_uint256_$returns$_t_bytes32_$_t_address_$", + "typeString": "function (uint8,uint256) view external returns (bytes32,address)" + } + }, + "id": 18249, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13655:45:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$", + "typeString": "tuple(bytes32,address)" + } + }, + "src": "13644:56:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18251, + "nodeType": "ExpressionStatement", + "src": "13644:56:47" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 18256, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18252, + "name": "_sto", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18239, + "src": "13714:4:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 18254, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13730:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 18253, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "13722:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 18255, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13722:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13714:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 18259, + "nodeType": "IfStatement", + "src": "13710:48:47", + "trueBody": { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 18257, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13753:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 18237, + "id": 18258, + "nodeType": "Return", + "src": "13746:12:47" + } + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 18260, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13775:4:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 18237, + "id": 18261, + "nodeType": "Return", + "src": "13768:11:47" + } + ] + }, + "documentation": "@notice Internal function use to know whether the STO is attached or not", + "id": 18263, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "isSTOAttached", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18234, + "nodeType": "ParameterList", + "parameters": [], + "src": "13581:2:47" + }, + "payable": false, + "returnParameters": { + "id": 18237, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18236, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 18263, + "src": "13606:4:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 18235, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "13606:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13605:6:47" + }, + "scope": 18264, + "src": "13559:227:47", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + } + ], + "scope": 18265, + "src": "759:13030:47" + } + ], + "src": "0:13790:47" + }, + "legacyAST": { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/TransferManager/GeneralTransferManager.sol", + "exportedSymbols": { + "GeneralTransferManager": [ + 18264 + ] + }, + "id": 18265, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 17587, + "literals": [ + "solidity", + "^", + "0.4", + ".24" + ], + "nodeType": "PragmaDirective", + "src": "0:24:47" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/TransferManager/ITransferManager.sol", + "file": "./ITransferManager.sol", + "id": 17588, + "nodeType": "ImportDirective", + "scope": 18265, + "sourceUnit": 18462, + "src": "26:32:47", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "openzeppelin-solidity/contracts/math/SafeMath.sol", + "file": "openzeppelin-solidity/contracts/math/SafeMath.sol", + "id": 17589, + "nodeType": "ImportDirective", + "scope": 18265, + "sourceUnit": 22697, + "src": "59:59:47", + "symbolAliases": [], + "unitAlias": "" + }, + { + "baseContracts": [ + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 17590, + "name": "ITransferManager", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 18461, + "src": "794:16:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITransferManager_$18461", + "typeString": "contract ITransferManager" + } + }, + "id": 17591, + "nodeType": "InheritanceSpecifier", + "src": "794:16:47" + } + ], + "contractDependencies": [ + 412, + 9596, + 18461 + ], + "contractKind": "contract", + "documentation": "@title Transfer Manager module for core transfer validation functionality", + "fullyImplemented": true, + "id": 18264, + "linearizedBaseContracts": [ + 18264, + 18461, + 412, + 9596 + ], + "name": "GeneralTransferManager", + "nodeType": "ContractDefinition", + "nodes": [ + { + "id": 17594, + "libraryName": { + "contractScope": null, + "id": 17592, + "name": "SafeMath", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 22696, + "src": "824:8:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SafeMath_$22696", + "typeString": "library SafeMath" + } + }, + "nodeType": "UsingForDirective", + "src": "818:27:47", + "typeName": { + "id": 17593, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "837:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "constant": false, + "id": 17599, + "name": "issuanceAddress", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "891:43:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17595, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "891:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17597, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "932:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17596, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "924:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 17598, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "924:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17604, + "name": "signingAddress", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "988:42:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17600, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "988:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17602, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1028:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17601, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1020:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 17603, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1020:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "public" + }, + { + "constant": true, + "id": 17607, + "name": "WHITELIST", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1037:47:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 17605, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1037:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "57484954454c495354", + "id": 17606, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1073:11:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_0af0c3ebe77999ca20698e1ff25f812bf82409a59d21ca15a41f39e0ce9f2500", + "typeString": "literal_string \"WHITELIST\"" + }, + "value": "WHITELIST" + }, + "visibility": "public" + }, + { + "constant": true, + "id": 17610, + "name": "FLAGS", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1090:39:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 17608, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1090:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "464c414753", + "id": 17609, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1122:7:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_343c07b3fb8ec1ffc9ce674026a727b988856209732b2202571e75a0996b3a37", + "typeString": "literal_string \"FLAGS\"" + }, + "value": "FLAGS" + }, + "visibility": "public" + }, + { + "canonicalName": "GeneralTransferManager.TimeRestriction", + "id": 17619, + "members": [ + { + "constant": false, + "id": 17612, + "name": "fromTime", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1254:16:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17611, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1254:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17614, + "name": "toTime", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1280:14:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17613, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1280:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17616, + "name": "expiryTime", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1304:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17615, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1304:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17618, + "name": "canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 17619, + "src": "1332:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17617, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1332:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "TimeRestriction", + "nodeType": "StructDefinition", + "scope": 18264, + "src": "1221:136:47", + "visibility": "public" + }, + { + "constant": false, + "id": 17623, + "name": "whitelist", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1540:53:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction)" + }, + "typeName": { + "id": 17622, + "keyType": { + "id": 17620, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1549:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "1540:36:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction)" + }, + "valueType": { + "contractScope": null, + "id": 17621, + "name": "TimeRestriction", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 17619, + "src": "1560:15:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage_ptr", + "typeString": "struct GeneralTransferManager.TimeRestriction" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 17626, + "name": "allowAllTransfers", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1669:37:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17624, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1669:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 17625, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1701:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17629, + "name": "allowAllWhitelistTransfers", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1799:46:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17627, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1799:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 17628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1840:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17632, + "name": "allowAllWhitelistIssuances", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "1938:45:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17630, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1938:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 17631, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1979:4:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 17635, + "name": "allowAllBurnTransfers", + "nodeType": "VariableDeclaration", + "scope": 18264, + "src": "2047:41:47", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17633, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2047:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 17634, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2083:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "anonymous": false, + "documentation": null, + "id": 17639, + "name": "LogChangeIssuanceAddress", + "nodeType": "EventDefinition", + "parameters": { + "id": 17638, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17637, + "indexed": false, + "name": "_issuanceAddress", + "nodeType": "VariableDeclaration", + "scope": 17639, + "src": "2172:24:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17636, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2172:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2171:26:47" + }, + "src": "2141:57:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17643, + "name": "LogAllowAllTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 17642, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17641, + "indexed": false, + "name": "_allowAllTransfers", + "nodeType": "VariableDeclaration", + "scope": 17643, + "src": "2309:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17640, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2309:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2308:25:47" + }, + "src": "2282:52:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17647, + "name": "LogAllowAllWhitelistTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 17646, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17645, + "indexed": false, + "name": "_allowAllWhitelistTransfers", + "nodeType": "VariableDeclaration", + "scope": 17647, + "src": "2463:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17644, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2463:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2462:34:47" + }, + "src": "2427:70:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17651, + "name": "LogAllowAllWhitelistIssuances", + "nodeType": "EventDefinition", + "parameters": { + "id": 17650, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17649, + "indexed": false, + "name": "_allowAllWhitelistIssuances", + "nodeType": "VariableDeclaration", + "scope": 17651, + "src": "2626:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17648, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2626:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2625:34:47" + }, + "src": "2590:70:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17655, + "name": "LogAllowAllBurnTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 17654, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17653, + "indexed": false, + "name": "_allowAllBurnTransfers", + "nodeType": "VariableDeclaration", + "scope": 17655, + "src": "2779:27:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17652, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2779:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2778:29:47" + }, + "src": "2748:60:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17659, + "name": "LogChangeSigningAddress", + "nodeType": "EventDefinition", + "parameters": { + "id": 17658, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17657, + "indexed": false, + "name": "_signingAddress", + "nodeType": "VariableDeclaration", + "scope": 17659, + "src": "2919:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17656, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2919:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2918:25:47" + }, + "src": "2889:55:47" + }, + { + "anonymous": false, + "documentation": null, + "id": 17675, + "name": "LogModifyWhitelist", + "nodeType": "EventDefinition", + "parameters": { + "id": 17674, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17661, + "indexed": false, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3060:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17660, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3060:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17663, + "indexed": false, + "name": "_dateAdded", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3087:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17662, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3087:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17665, + "indexed": false, + "name": "_addedBy", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3115:16:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17664, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3115:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17667, + "indexed": false, + "name": "_fromTime", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3141:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17666, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3141:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17669, + "indexed": false, + "name": "_toTime", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3168:15:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17668, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3168:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17671, + "indexed": false, + "name": "_expiryTime", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3193:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17670, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3193:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17673, + "indexed": false, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 17675, + "src": "3222:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17672, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3222:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3050:197:47" + }, + "src": "3026:222:47" + }, + { + "body": { + "id": 17686, + "nodeType": "Block", + "src": "3524:7:47", + "statements": [] + }, + "documentation": "@notice Constructor\n@param _securityToken Address of the security token\n@param _polyAddress Address of the polytoken", + "id": 17687, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17682, + "name": "_securityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17677, + "src": "3490:14:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 17683, + "name": "_polyAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17679, + "src": "3506:12:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 17684, + "modifierName": { + "argumentTypes": null, + "id": 17681, + "name": "IModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9596, + "src": "3482:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModule_$9596_$", + "typeString": "type(contract IModule)" + } + }, + "nodeType": "ModifierInvocation", + "src": "3482:37:47" + } + ], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17680, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17677, + "name": "_securityToken", + "nodeType": "VariableDeclaration", + "scope": 17687, + "src": "3421:22:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17676, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3421:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17679, + "name": "_polyAddress", + "nodeType": "VariableDeclaration", + "scope": 17687, + "src": "3445:20:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17678, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3445:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3420:46:47" + }, + "payable": false, + "returnParameters": { + "id": 17685, + "nodeType": "ParameterList", + "parameters": [], + "src": "3524:0:47" + }, + "scope": 18264, + "src": "3408:123:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17696, + "nodeType": "Block", + "src": "3682:33:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17693, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3706:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17692, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3699:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 17694, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3699:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "functionReturnParameters": 17691, + "id": 17695, + "nodeType": "Return", + "src": "3692:16:47" + } + ] + }, + "documentation": "@notice This function returns the signature of configure function", + "id": 17697, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getInitFunction", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17688, + "nodeType": "ParameterList", + "parameters": [], + "src": "3650:2:47" + }, + "payable": false, + "returnParameters": { + "id": 17691, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17690, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17697, + "src": "3674:6:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 17689, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "3674:6:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3673:8:47" + }, + "scope": 18264, + "src": "3626:89:47", + "stateMutability": "pure", + "superFunction": 9475, + "visibility": "public" + }, + { + "body": { + "id": 17713, + "nodeType": "Block", + "src": "3928:108:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17707, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17705, + "name": "issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17599, + "src": "3938:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17706, + "name": "_issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17699, + "src": "3956:16:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3938:34:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 17708, + "nodeType": "ExpressionStatement", + "src": "3938:34:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17710, + "name": "_issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17699, + "src": "4012:16:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17709, + "name": "LogChangeIssuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17639, + "src": "3987:24:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 17711, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3987:42:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17712, + "nodeType": "EmitStatement", + "src": "3982:47:47" + } + ] + }, + "documentation": "@notice Used to change the Issuance Address\n@param _issuanceAddress new address for the issuance", + "id": 17714, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17702, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "3921:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17703, + "modifierName": { + "argumentTypes": null, + "id": 17701, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "3912:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "3912:15:47" + } + ], + "name": "changeIssuanceAddress", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17700, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17699, + "name": "_issuanceAddress", + "nodeType": "VariableDeclaration", + "scope": 17714, + "src": "3879:24:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17698, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3879:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3878:26:47" + }, + "payable": false, + "returnParameters": { + "id": 17704, + "nodeType": "ParameterList", + "parameters": [], + "src": "3928:0:47" + }, + "scope": 18264, + "src": "3848:188:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17730, + "nodeType": "Block", + "src": "4245:104:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17722, + "name": "signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17604, + "src": "4255:14:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17723, + "name": "_signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17716, + "src": "4272:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4255:32:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 17725, + "nodeType": "ExpressionStatement", + "src": "4255:32:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17727, + "name": "_signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17716, + "src": "4326:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17726, + "name": "LogChangeSigningAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17659, + "src": "4302:23:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 17728, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4302:40:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17729, + "nodeType": "EmitStatement", + "src": "4297:45:47" + } + ] + }, + "documentation": "@notice Used to change the Sigining Address\n@param _signingAddress new address for the signing", + "id": 17731, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17719, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "4238:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17720, + "modifierName": { + "argumentTypes": null, + "id": 17718, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "4229:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "4229:15:47" + } + ], + "name": "changeSigningAddress", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17717, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17716, + "name": "_signingAddress", + "nodeType": "VariableDeclaration", + "scope": 17731, + "src": "4197:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17715, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4197:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4196:25:47" + }, + "payable": false, + "returnParameters": { + "id": 17721, + "nodeType": "ParameterList", + "parameters": [], + "src": "4245:0:47" + }, + "scope": 18264, + "src": "4167:182:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17747, + "nodeType": "Block", + "src": "4692:110:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17741, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17739, + "name": "allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17626, + "src": "4702:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17740, + "name": "_allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17733, + "src": "4722:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4702:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17742, + "nodeType": "ExpressionStatement", + "src": "4702:38:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17744, + "name": "_allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17733, + "src": "4776:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17743, + "name": "LogAllowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17643, + "src": "4755:20:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4755:40:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17746, + "nodeType": "EmitStatement", + "src": "4750:45:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It refers there are no transfer restrictions, for any addresses\nfalse - It refers transfers are restricted for all addresses.\n@param _allowAllTransfers flag value", + "id": 17748, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17736, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "4685:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17737, + "modifierName": { + "argumentTypes": null, + "id": 17735, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "4676:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "4676:15:47" + } + ], + "name": "changeAllowAllTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17734, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17733, + "name": "_allowAllTransfers", + "nodeType": "VariableDeclaration", + "scope": 17748, + "src": "4644:23:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17732, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4644:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4643:25:47" + }, + "payable": false, + "returnParameters": { + "id": 17738, + "nodeType": "ParameterList", + "parameters": [], + "src": "4692:0:47" + }, + "scope": 18264, + "src": "4611:191:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17764, + "nodeType": "Block", + "src": "5195:146:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17758, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17756, + "name": "allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17629, + "src": "5205:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17757, + "name": "_allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17750, + "src": "5234:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5205:56:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17759, + "nodeType": "ExpressionStatement", + "src": "5205:56:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17761, + "name": "_allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17750, + "src": "5306:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17760, + "name": "LogAllowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17647, + "src": "5276:29:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17762, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5276:58:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17763, + "nodeType": "EmitStatement", + "src": "5271:63:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It refers that time lock is ignored for transfers (address must still be on whitelist)\nfalse - It refers transfers are restricted for all addresses.\n@param _allowAllWhitelistTransfers flag value", + "id": 17765, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17753, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "5188:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17754, + "modifierName": { + "argumentTypes": null, + "id": 17752, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "5179:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5179:15:47" + } + ], + "name": "changeAllowAllWhitelistTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17751, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17750, + "name": "_allowAllWhitelistTransfers", + "nodeType": "VariableDeclaration", + "scope": 17765, + "src": "5138:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17749, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5138:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5137:34:47" + }, + "payable": false, + "returnParameters": { + "id": 17755, + "nodeType": "ParameterList", + "parameters": [], + "src": "5195:0:47" + }, + "scope": 18264, + "src": "5096:245:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17781, + "nodeType": "Block", + "src": "5734:146:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17775, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17773, + "name": "allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17632, + "src": "5744:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17774, + "name": "_allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17767, + "src": "5773:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5744:56:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17776, + "nodeType": "ExpressionStatement", + "src": "5744:56:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17778, + "name": "_allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17767, + "src": "5845:27:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17777, + "name": "LogAllowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17651, + "src": "5815:29:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17779, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5815:58:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17780, + "nodeType": "EmitStatement", + "src": "5810:63:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It refers that time lock is ignored for issuances (address must still be on whitelist)\nfalse - It refers transfers are restricted for all addresses.\n@param _allowAllWhitelistIssuances flag value", + "id": 17782, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17770, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "5727:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17771, + "modifierName": { + "argumentTypes": null, + "id": 17769, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "5718:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5718:15:47" + } + ], + "name": "changeAllowAllWhitelistIssuances", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17768, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17767, + "name": "_allowAllWhitelistIssuances", + "nodeType": "VariableDeclaration", + "scope": 17782, + "src": "5677:32:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17766, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5677:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5676:34:47" + }, + "payable": false, + "returnParameters": { + "id": 17772, + "nodeType": "ParameterList", + "parameters": [], + "src": "5734:0:47" + }, + "scope": 18264, + "src": "5635:245:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17798, + "nodeType": "Block", + "src": "6182:126:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17792, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 17790, + "name": "allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17635, + "src": "6192:21:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 17791, + "name": "_allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17784, + "src": "6216:22:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "6192:46:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17793, + "nodeType": "ExpressionStatement", + "src": "6192:46:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17795, + "name": "_allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17784, + "src": "6278:22:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17794, + "name": "LogAllowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17655, + "src": "6253:24:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$returns$__$", + "typeString": "function (bool)" + } + }, + "id": 17796, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6253:48:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17797, + "nodeType": "EmitStatement", + "src": "6248:53:47" + } + ] + }, + "documentation": "@notice Used to change the flag\ntrue - It allow to burn the tokens\nfalse - It deactivate the burning mechanism.\n@param _allowAllBurnTransfers flag value", + "id": 17799, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17787, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "6175:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17788, + "modifierName": { + "argumentTypes": null, + "id": 17786, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "6166:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "6166:15:47" + } + ], + "name": "changeAllowAllBurnTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17785, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17784, + "name": "_allowAllBurnTransfers", + "nodeType": "VariableDeclaration", + "scope": 17799, + "src": "6130:27:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17783, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "6130:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6129:29:47" + }, + "payable": false, + "returnParameters": { + "id": 17789, + "nodeType": "ParameterList", + "parameters": [], + "src": "6182:0:47" + }, + "scope": 18264, + "src": "6093:215:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 17914, + "nodeType": "Block", + "src": "6823:1121:47", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 17813, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "6837:7:47", + "subExpression": { + "argumentTypes": null, + "id": 17812, + "name": "paused", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 364, + "src": "6838:6:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17910, + "nodeType": "IfStatement", + "src": "6833:1079:47", + "trueBody": { + "id": 17909, + "nodeType": "Block", + "src": "6846:1066:47", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 17814, + "name": "allowAllTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17626, + "src": "6864:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17819, + "nodeType": "IfStatement", + "src": "6860:140:47", + "trueBody": { + "id": 17818, + "nodeType": "Block", + "src": "6883:117:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17815, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "6973:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17816, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "6973:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17817, + "nodeType": "Return", + "src": "6966:19:47" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17827, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17820, + "name": "allowAllBurnTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17635, + "src": "7017:21:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 17825, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17821, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7043:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 17823, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7058:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 17822, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "7050:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 17824, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7050:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "7043:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17826, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7042:19:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7017:44:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17832, + "nodeType": "IfStatement", + "src": "7013:102:47", + "trueBody": { + "id": 17831, + "nodeType": "Block", + "src": "7063:52:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17828, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7088:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17829, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7088:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17830, + "nodeType": "Return", + "src": "7081:19:47" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "id": 17833, + "name": "allowAllWhitelistTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17629, + "src": "7132:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17849, + "nodeType": "IfStatement", + "src": "7128:222:47", + "trueBody": { + "id": 17848, + "nodeType": "Block", + "src": "7160:190:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17840, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17835, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7281:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17834, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7269:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17836, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7269:16:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17838, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7301:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17837, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7289:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17839, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7289:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7269:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17841, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7268:40:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17844, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7326:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17845, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7326:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "id": 17846, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "7268:67:47", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17842, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7311:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17843, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7311:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17847, + "nodeType": "Return", + "src": "7261:74:47" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17854, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17850, + "name": "allowAllWhitelistIssuances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17632, + "src": "7367:26:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 17853, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17851, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7397:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 17852, + "name": "issuanceAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17599, + "src": "7406:15:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "7397:24:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7367:54:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17878, + "nodeType": "IfStatement", + "src": "7363:271:47", + "trueBody": { + "id": 17877, + "nodeType": "Block", + "src": "7423:211:47", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 17859, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "7445:29:47", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17855, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "7446:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17857, + "indexExpression": { + "argumentTypes": null, + "id": 17856, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7456:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7446:14:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17858, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "canBuyFromSTO", + "nodeType": "MemberAccess", + "referencedDeclaration": 17618, + "src": "7446:28:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 17860, + "name": "isSTOAttached", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18263, + "src": "7478:13:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_bool_$", + "typeString": "function () view returns (bool)" + } + }, + "id": 17861, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7478:15:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7445:48:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 17867, + "nodeType": "IfStatement", + "src": "7441:111:47", + "trueBody": { + "id": 17866, + "nodeType": "Block", + "src": "7495:57:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17863, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7524:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17864, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7524:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17865, + "nodeType": "Return", + "src": "7517:16:47" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17869, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7588:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17868, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7576:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17870, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7576:16:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17873, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7610:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17874, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7610:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "id": 17875, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "7576:43:47", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17871, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7595:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17872, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7595:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17876, + "nodeType": "Return", + "src": "7569:50:47" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17901, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17888, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17880, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7760:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17879, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7748:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17881, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7748:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17887, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17882, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "7770:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17884, + "indexExpression": { + "argumentTypes": null, + "id": 17883, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17801, + "src": "7780:5:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7770:16:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17885, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "fromTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17612, + "src": "7770:25:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 17886, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "7799:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7770:32:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7748:54:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17889, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7747:56:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 17899, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17891, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7836:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 17890, + "name": "onWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18233, + "src": "7824:11:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_bool_$", + "typeString": "function (address) view returns (bool)" + } + }, + "id": 17892, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7824:16:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17898, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17893, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "7844:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17895, + "indexExpression": { + "argumentTypes": null, + "id": 17894, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17803, + "src": "7854:3:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7844:14:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17896, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "toTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17614, + "src": "7844:21:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 17897, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "7869:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7844:28:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7824:48:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17900, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7823:50:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "7747:126:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 17902, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "7746:128:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17905, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7892:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17906, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7892:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "id": 17907, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "7746:155:47", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17903, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7877:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17904, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7877:12:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17908, + "nodeType": "Return", + "src": "7739:162:47" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17911, + "name": "Result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18425, + "src": "7928:6:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18425_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 17912, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "NA", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7928:9:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "functionReturnParameters": 17811, + "id": 17913, + "nodeType": "Return", + "src": "7921:16:47" + } + ] + }, + "documentation": "@notice default implementation of verifyTransfer used by SecurityToken\nIf the transfer request comes from the STO, it only checks that the investor is in the whitelist\nIf the transfer request comes from a token holder, it checks that:\na) Both are on the whitelist\nb) Seller's sale lockup period is over\nc) Buyer's purchase lockup is over", + "id": 17915, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "verifyTransfer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17808, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17801, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6727:13:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17800, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6727:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17803, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6742:11:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17802, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6742:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17805, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6755:7:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17804, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6755:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17807, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6776:4:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17806, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "6776:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6726:73:47" + }, + "payable": false, + "returnParameters": { + "id": 17811, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17810, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 17915, + "src": "6815:6:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + }, + "typeName": { + "contractScope": null, + "id": 17809, + "name": "Result", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 18425, + "src": "6815:6:47", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18425", + "typeString": "enum ITransferManager.Result" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6814:8:47" + }, + "scope": 18264, + "src": "6703:1241:47", + "stateMutability": "nonpayable", + "superFunction": 18438, + "visibility": "public" + }, + { + "body": { + "id": 17953, + "nodeType": "Block", + "src": "8678:324:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 17940, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 17931, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "8798:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 17933, + "indexExpression": { + "argumentTypes": null, + "id": 17932, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17917, + "src": "8808:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "8798:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17935, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17919, + "src": "8837:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17936, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17921, + "src": "8848:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17937, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17923, + "src": "8857:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17938, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17925, + "src": "8870:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17934, + "name": "TimeRestriction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17619, + "src": "8821:15:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_TimeRestriction_$17619_storage_ptr_$", + "typeString": "type(struct GeneralTransferManager.TimeRestriction storage pointer)" + } + }, + "id": 17939, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8821:64:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_memory", + "typeString": "struct GeneralTransferManager.TimeRestriction memory" + } + }, + "src": "8798:87:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 17941, + "nodeType": "ExpressionStatement", + "src": "8798:87:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 17943, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17917, + "src": "8919:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 17944, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "8930:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17945, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23249, + "src": "8935:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 17946, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "8935:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 17947, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17919, + "src": "8947:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17948, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17921, + "src": "8958:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17949, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17923, + "src": "8967:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 17950, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17925, + "src": "8980:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 17942, + "name": "LogModifyWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17675, + "src": "8900:18:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (address,uint256,address,uint256,uint256,uint256,bool)" + } + }, + "id": 17951, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8900:95:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17952, + "nodeType": "EmitStatement", + "src": "8895:100:47" + } + ] + }, + "documentation": "@notice adds or removes addresses from the whitelist.\n@param _investor is the address to whitelist\n@param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens\n@param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n@param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC\n@param _canBuyFromSTO is used to know whether the investor is restricted investor or not.", + "id": 17954, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17928, + "name": "WHITELIST", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17607, + "src": "8667:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17929, + "modifierName": { + "argumentTypes": null, + "id": 17927, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "8658:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "8658:19:47" + } + ], + "name": "modifyWhitelist", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17926, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17917, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8554:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 17916, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8554:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17919, + "name": "_fromTime", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8573:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17918, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8573:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17921, + "name": "_toTime", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8592:15:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17920, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8592:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17923, + "name": "_expiryTime", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8609:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 17922, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8609:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17925, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 17954, + "src": "8630:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 17924, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "8630:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "8553:97:47" + }, + "payable": false, + "returnParameters": { + "id": 17930, + "nodeType": "ParameterList", + "parameters": [], + "src": "8678:0:47" + }, + "scope": 18264, + "src": "8529:473:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 18042, + "nodeType": "Block", + "src": "9798:522:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17980, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17976, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17957, + "src": "9816:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 17977, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9816:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17978, + "name": "_fromTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17960, + "src": "9837:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17979, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9837:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9816:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e67746873", + "id": 17981, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9856:26:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + }, + "value": "Mismatched input lengths" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + } + ], + "id": 17975, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "9808:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 17982, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9808:75:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17983, + "nodeType": "ExpressionStatement", + "src": "9808:75:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17989, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17985, + "name": "_fromTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17960, + "src": "9901:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17986, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9901:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17987, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "9922:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17988, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9922:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9901:36:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e67746873", + "id": 17990, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9939:26:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + }, + "value": "Mismatched input lengths" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + } + ], + "id": 17984, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "9893:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 17991, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9893:73:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 17992, + "nodeType": "ExpressionStatement", + "src": "9893:73:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 17998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17994, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "9984:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17995, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9984:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 17996, + "name": "_expiryTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17966, + "src": "10003:12:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 17997, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10003:19:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9984:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e67746873", + "id": 17999, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10024:26:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + }, + "value": "Mismatched input lengths" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_757ac971b3c89ff6729d1b818f9eb2011ff93a983cd352fb4a93d3214c1015fe", + "typeString": "literal_string \"Mismatched input lengths\"" + } + ], + "id": 17993, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "9976:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18000, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9976:75:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18001, + "nodeType": "ExpressionStatement", + "src": "9976:75:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18007, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18003, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17969, + "src": "10069:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_memory_ptr", + "typeString": "bool[] memory" + } + }, + "id": 18004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10069:21:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18005, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "10094:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18006, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10094:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10069:40:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69736d61746368656420696e707574206c656e677468", + "id": 18008, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10111:25:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_105cd25b3fa111d79edd195a9110213618d4a0b70897083c4c45e06854cf081f", + "typeString": "literal_string \"Mismatched input length\"" + }, + "value": "Mismatched input length" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_105cd25b3fa111d79edd195a9110213618d4a0b70897083c4c45e06854cf081f", + "typeString": "literal_string \"Mismatched input length\"" + } + ], + "id": 18002, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "10061:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18009, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10061:76:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18010, + "nodeType": "ExpressionStatement", + "src": "10061:76:47" + }, + { + "body": { + "id": 18040, + "nodeType": "Block", + "src": "10195:119:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18023, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17957, + "src": "10225:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 18025, + "indexExpression": { + "argumentTypes": null, + "id": 18024, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10236:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10225:13:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18026, + "name": "_fromTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17960, + "src": "10240:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18028, + "indexExpression": { + "argumentTypes": null, + "id": 18027, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10251:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10240:13:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18029, + "name": "_toTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17963, + "src": "10255:8:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18031, + "indexExpression": { + "argumentTypes": null, + "id": 18030, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10264:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10255:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18032, + "name": "_expiryTimes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17966, + "src": "10268:12:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 18034, + "indexExpression": { + "argumentTypes": null, + "id": 18033, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10281:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10268:15:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18035, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17969, + "src": "10285:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_memory_ptr", + "typeString": "bool[] memory" + } + }, + "id": 18037, + "indexExpression": { + "argumentTypes": null, + "id": 18036, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10300:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10285:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 18022, + "name": "modifyWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17954, + "src": "10209:15:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (address,uint256,uint256,uint256,bool)" + } + }, + "id": 18038, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10209:94:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18039, + "nodeType": "ExpressionStatement", + "src": "10209:94:47" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18018, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18015, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10167:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18016, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17957, + "src": "10171:10:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 18017, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10171:17:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10167:21:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 18041, + "initializationExpression": { + "assignments": [ + 18012 + ], + "declarations": [ + { + "constant": false, + "id": 18012, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "10152:9:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18011, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10152:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18014, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 18013, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10164:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "10152:13:47" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 18020, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "10190:3:47", + "subExpression": { + "argumentTypes": null, + "id": 18019, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18012, + "src": "10190:1:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 18021, + "nodeType": "ExpressionStatement", + "src": "10190:3:47" + }, + "nodeType": "ForStatement", + "src": "10147:167:47" + } + ] + }, + "documentation": "@notice adds or removes addresses from the whitelist.\n@param _investors List of the addresses to whitelist\n@param _fromTimes An array of the moment when the sale lockup period ends and the investor can freely sell his tokens\n@param _toTimes An array of the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n@param _expiryTimes An array of the moment till investors KYC will be validated. After that investor need to do re-KYC\n@param _canBuyFromSTO An array of boolean values", + "id": 18043, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 17972, + "name": "WHITELIST", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17607, + "src": "9787:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 17973, + "modifierName": { + "argumentTypes": null, + "id": 17971, + "name": "withPerm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9518, + "src": "9778:8:47", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_bytes32_$", + "typeString": "modifier (bytes32)" + } + }, + "nodeType": "ModifierInvocation", + "src": "9778:19:47" + } + ], + "name": "modifyWhitelistMulti", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17970, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 17957, + "name": "_investors", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9623:20:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 17955, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9623:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 17956, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9623:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17960, + "name": "_fromTimes", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9653:20:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 17958, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9653:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 17959, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9653:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17963, + "name": "_toTimes", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9683:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 17961, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9683:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 17962, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9683:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17966, + "name": "_expiryTimes", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9711:22:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 17964, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9711:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 17965, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9711:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 17969, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 18043, + "src": "9743:21:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_memory_ptr", + "typeString": "bool[]" + }, + "typeName": { + "baseType": { + "id": 17967, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "9743:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 17968, + "length": null, + "nodeType": "ArrayTypeName", + "src": "9743:6:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bool_$dyn_storage_ptr", + "typeString": "bool[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9613:157:47" + }, + "payable": false, + "returnParameters": { + "id": 17974, + "nodeType": "ParameterList", + "parameters": [], + "src": "9798:0:47" + }, + "scope": 18264, + "src": "9584:736:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 18125, + "nodeType": "Block", + "src": "11484:619:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18069, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18067, + "name": "_validFrom", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18055, + "src": "11502:10:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 18068, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "11516:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11502:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "56616c696446726f6d20697320746f6f206561726c79", + "id": 18070, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11521:24:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_99e48cd3a89cd958b606f09b46fee13c6f02a8c1cabd819bdc259be60f8be245", + "typeString": "literal_string \"ValidFrom is too early\"" + }, + "value": "ValidFrom is too early" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_99e48cd3a89cd958b606f09b46fee13c6f02a8c1cabd819bdc259be60f8be245", + "typeString": "literal_string \"ValidFrom is too early\"" + } + ], + "id": 18066, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "11494:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18071, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11494:52:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18072, + "nodeType": "ExpressionStatement", + "src": "11494:52:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18076, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18074, + "name": "_validTo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18057, + "src": "11564:8:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 18075, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "11576:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11564:15:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "56616c6964546f20697320746f6f206c617465", + "id": 18077, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11581:21:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_32b35358d9cb029ce5f1705ced20cd49735d5c5348949ad9326e100596c13439", + "typeString": "literal_string \"ValidTo is too late\"" + }, + "value": "ValidTo is too late" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_32b35358d9cb029ce5f1705ced20cd49735d5c5348949ad9326e100596c13439", + "typeString": "literal_string \"ValidTo is too late\"" + } + ], + "id": 18073, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "11556:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18078, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11556:47:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18079, + "nodeType": "ExpressionStatement", + "src": "11556:47:47" + }, + { + "assignments": [ + 18081 + ], + "declarations": [ + { + "constant": false, + "id": 18081, + "name": "hash", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11613:12:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18080, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "11613:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18095, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18085, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23406, + "src": "11655:4:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_GeneralTransferManager_$18264", + "typeString": "contract GeneralTransferManager" + } + }, + { + "argumentTypes": null, + "id": 18086, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18045, + "src": "11661:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 18087, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18047, + "src": "11672:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18088, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18049, + "src": "11683:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18089, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18051, + "src": "11692:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18090, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18053, + "src": "11705:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "id": 18091, + "name": "_validFrom", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18055, + "src": "11721:10:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18092, + "name": "_validTo", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18057, + "src": "11733:8:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_GeneralTransferManager_$18264", + "typeString": "contract GeneralTransferManager" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 18083, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23236, + "src": "11638:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 18084, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11638:16:47", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 18093, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11638:104:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 18082, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23243, + "src": "11628:9:47", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 18094, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11628:115:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11613:130:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18097, + "name": "hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18081, + "src": "11762:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18098, + "name": "_v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18059, + "src": "11768:2:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "id": 18099, + "name": "_r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18061, + "src": "11772:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18100, + "name": "_s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18063, + "src": "11776:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 18096, + "name": "checkSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18168, + "src": "11753:8:47", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_uint8_$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,uint8,bytes32,bytes32) view" + } + }, + "id": 18101, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11753:26:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18102, + "nodeType": "ExpressionStatement", + "src": "11753:26:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18112, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18103, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "11899:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18105, + "indexExpression": { + "argumentTypes": null, + "id": 18104, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18045, + "src": "11909:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "11899:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18107, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18047, + "src": "11938:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18108, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18049, + "src": "11949:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18109, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18051, + "src": "11958:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18110, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18053, + "src": "11971:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 18106, + "name": "TimeRestriction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17619, + "src": "11922:15:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_TimeRestriction_$17619_storage_ptr_$", + "typeString": "type(struct GeneralTransferManager.TimeRestriction storage pointer)" + } + }, + "id": 18111, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11922:64:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_memory", + "typeString": "struct GeneralTransferManager.TimeRestriction memory" + } + }, + "src": "11899:87:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18113, + "nodeType": "ExpressionStatement", + "src": "11899:87:47" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18115, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18045, + "src": "12020:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 18116, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "12031:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 18117, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23249, + "src": "12036:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 18118, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12036:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 18119, + "name": "_fromTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18047, + "src": "12048:9:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18120, + "name": "_toTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18049, + "src": "12059:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18121, + "name": "_expiryTime", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18051, + "src": "12068:11:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 18122, + "name": "_canBuyFromSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18053, + "src": "12081:14:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 18114, + "name": "LogModifyWhitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17675, + "src": "12001:18:47", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (address,uint256,address,uint256,uint256,uint256,bool)" + } + }, + "id": 18123, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12001:95:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18124, + "nodeType": "EmitStatement", + "src": "11996:100:47" + } + ] + }, + "documentation": "@notice adds or removes addresses from the whitelist - can be called by anyone with a valid signature\n@param _investor is the address to whitelist\n@param _fromTime is the moment when the sale lockup period ends and the investor can freely sell his tokens\n@param _toTime is the moment when the purchase lockup period ends and the investor can freely purchase tokens from others\n@param _expiryTime is the moment till investors KYC will be validated. After that investor need to do re-KYC\n@param _canBuyFromSTO is used to know whether the investor is restricted investor or not.\n@param _validFrom is the time that this signature is valid from\n@param _validTo is the time that this signature is valid until\n@param _v issuer signature\n@param _r issuer signature\n@param _s issuer signature", + "id": 18126, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "modifyWhitelistSigned", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18064, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18045, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11231:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18044, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "11231:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18047, + "name": "_fromTime", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11258:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18046, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11258:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18049, + "name": "_toTime", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11285:15:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18048, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11285:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18051, + "name": "_expiryTime", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11310:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18050, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11310:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18053, + "name": "_canBuyFromSTO", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11339:19:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 18052, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "11339:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18055, + "name": "_validFrom", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11368:18:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18054, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11368:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18057, + "name": "_validTo", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11396:16:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 18056, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11396:7:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18059, + "name": "_v", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11422:8:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 18058, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "11422:5:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18061, + "name": "_r", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11440:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18060, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "11440:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18063, + "name": "_s", + "nodeType": "VariableDeclaration", + "scope": 18126, + "src": "11460:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18062, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "11460:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "11221:255:47" + }, + "payable": false, + "returnParameters": { + "id": 18065, + "nodeType": "ParameterList", + "parameters": [], + "src": "11484:0:47" + }, + "scope": 18264, + "src": "11191:912:47", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 18167, + "nodeType": "Block", + "src": "12250:399:47", + "statements": [ + { + "assignments": [ + 18138 + ], + "declarations": [ + { + "constant": false, + "id": 18138, + "name": "signer", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12418:14:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18137, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "12418:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18151, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "19457468657265756d205369676e6564204d6573736167653a0a3332", + "id": 18143, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12472:34:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73", + "typeString": "literal_string \"\u0019Ethereum Signed Message:\n32\"" + }, + "value": "\u0019Ethereum Signed Message:\n32" + }, + { + "argumentTypes": null, + "id": 18144, + "name": "_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18128, + "src": "12508:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73", + "typeString": "literal_string \"\u0019Ethereum Signed Message:\n32\"" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "argumentTypes": null, + "id": 18141, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23236, + "src": "12455:3:47", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 18142, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "12455:16:47", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 18145, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12455:59:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 18140, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23243, + "src": "12445:9:47", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 18146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12445:70:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18147, + "name": "_v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18130, + "src": "12517:2:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "id": 18148, + "name": "_r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18132, + "src": "12521:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 18149, + "name": "_s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18134, + "src": "12525:2:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 18139, + "name": "ecrecover", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23241, + "src": "12435:9:47", + "typeDescriptions": { + "typeIdentifier": "t_function_ecrecover_pure$_t_bytes32_$_t_uint8_$_t_bytes32_$_t_bytes32_$returns$_t_address_$", + "typeString": "function (bytes32,uint8,bytes32,bytes32) pure returns (address)" + } + }, + "id": 18150, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12435:93:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12418:110:47" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 18163, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 18159, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18153, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18138, + "src": "12546:6:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18155, + "name": "securityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9442, + "src": "12571:13:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 18154, + "name": "ISecurityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10038, + "src": "12556:14:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ISecurityToken_$10038_$", + "typeString": "type(contract ISecurityToken)" + } + }, + "id": 18156, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12556:29:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ISecurityToken_$10038", + "typeString": "contract ISecurityToken" + } + }, + "id": 18157, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "owner", + "nodeType": "MemberAccess", + "referencedDeclaration": 22700, + "src": "12556:35:47", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_address_$", + "typeString": "function () view external returns (address)" + } + }, + "id": 18158, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12556:37:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "12546:47:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 18162, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18160, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18138, + "src": "12597:6:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 18161, + "name": "signingAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17604, + "src": "12607:14:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "12597:24:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "12546:75:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e636f7272656374207369676e6572", + "id": 18164, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12623:18:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f959bac4fcb8350e440bda9ef2e133685bbcca7e96b8c2ce30bcb87b7e733c10", + "typeString": "literal_string \"Incorrect signer\"" + }, + "value": "Incorrect signer" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f959bac4fcb8350e440bda9ef2e133685bbcca7e96b8c2ce30bcb87b7e733c10", + "typeString": "literal_string \"Incorrect signer\"" + } + ], + "id": 18152, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23252, + 23253 + ], + "referencedDeclaration": 23253, + "src": "12538:7:47", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 18165, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12538:104:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18166, + "nodeType": "ExpressionStatement", + "src": "12538:104:47" + } + ] + }, + "documentation": "@notice used to verify the signature", + "id": 18168, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "checkSig", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18135, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18128, + "name": "_hash", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12187:13:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18127, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12187:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18130, + "name": "_v", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12202:8:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 18129, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "12202:5:47", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18132, + "name": "_r", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12212:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18131, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12212:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 18134, + "name": "_s", + "nodeType": "VariableDeclaration", + "scope": 18168, + "src": "12224:10:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 18133, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12224:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12186:49:47" + }, + "payable": false, + "returnParameters": { + "id": 18136, + "nodeType": "ParameterList", + "parameters": [], + "src": "12250:0:47" + }, + "scope": 18264, + "src": "12169:480:47", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 18198, + "nodeType": "Block", + "src": "12821:172:47", + "statements": [ + { + "assignments": [ + 18177 + ], + "declarations": [ + { + "constant": false, + "id": 18177, + "name": "allPermissions", + "nodeType": "VariableDeclaration", + "scope": 18199, + "src": "12831:31:47", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 18175, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12831:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18176, + "length": null, + "nodeType": "ArrayTypeName", + "src": "12831:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18183, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "32", + "id": 18181, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12879:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "id": 18180, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "12865:13:47", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_bytes32_$dyn_memory_$", + "typeString": "function (uint256) pure returns (bytes32[] memory)" + }, + "typeName": { + "baseType": { + "id": 18178, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12869:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18179, + "length": null, + "nodeType": "ArrayTypeName", + "src": "12869:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + } + }, + "id": 18182, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12865:16:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory", + "typeString": "bytes32[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12831:50:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18188, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18184, + "name": "allPermissions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18177, + "src": "12891:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 18186, + "indexExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 18185, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12906:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "12891:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 18187, + "name": "WHITELIST", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17607, + "src": "12911:9:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "12891:29:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18189, + "nodeType": "ExpressionStatement", + "src": "12891:29:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18194, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18190, + "name": "allPermissions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18177, + "src": "12930:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "id": 18192, + "indexExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 18191, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12945:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "12930:17:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 18193, + "name": "FLAGS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17610, + "src": "12950:5:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "12930:25:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18195, + "nodeType": "ExpressionStatement", + "src": "12930:25:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18196, + "name": "allPermissions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18177, + "src": "12972:14:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[] memory" + } + }, + "functionReturnParameters": 18173, + "id": 18197, + "nodeType": "Return", + "src": "12965:21:47" + } + ] + }, + "documentation": "@notice Return the permissions flag that are associated with general trnasfer manager", + "id": 18199, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getPermissions", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18169, + "nodeType": "ParameterList", + "parameters": [], + "src": "12787:2:47" + }, + "payable": false, + "returnParameters": { + "id": 18173, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18172, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 18199, + "src": "12810:9:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_memory_ptr", + "typeString": "bytes32[]" + }, + "typeName": { + "baseType": { + "id": 18170, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12810:7:47", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 18171, + "length": null, + "nodeType": "ArrayTypeName", + "src": "12810:9:47", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes32_$dyn_storage_ptr", + "typeString": "bytes32[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12809:11:47" + }, + "scope": 18264, + "src": "12764:229:47", + "stateMutability": "view", + "superFunction": 9568, + "visibility": "public" + }, + { + "body": { + "id": 18232, + "nodeType": "Block", + "src": "13299:158:47", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 18229, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 18220, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18211, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18206, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "13319:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18208, + "indexExpression": { + "argumentTypes": null, + "id": 18207, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18201, + "src": "13329:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13319:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18209, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "fromTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17612, + "src": "13319:29:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 18210, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13352:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13319:34:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18212, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13318:36:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18218, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18213, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "13359:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18215, + "indexExpression": { + "argumentTypes": null, + "id": 18214, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18201, + "src": "13369:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13359:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18216, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "toTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17614, + "src": "13359:27:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 18217, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13390:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13359:32:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18219, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13358:34:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13318:74:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18221, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13317:76:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 18227, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 18222, + "name": "whitelist", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 17623, + "src": "13410:9:47", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_struct$_TimeRestriction_$17619_storage_$", + "typeString": "mapping(address => struct GeneralTransferManager.TimeRestriction storage ref)" + } + }, + "id": 18224, + "indexExpression": { + "argumentTypes": null, + "id": 18223, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18201, + "src": "13420:9:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "13410:20:47", + "typeDescriptions": { + "typeIdentifier": "t_struct$_TimeRestriction_$17619_storage", + "typeString": "struct GeneralTransferManager.TimeRestriction storage ref" + } + }, + "id": 18225, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "expiryTime", + "nodeType": "MemberAccess", + "referencedDeclaration": 17616, + "src": "13410:31:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 18226, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23251, + "src": "13445:3:47", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13410:38:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18228, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13409:40:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13317:132:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 18230, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13316:134:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 18205, + "id": 18231, + "nodeType": "Return", + "src": "13309:141:47" + } + ] + }, + "documentation": "@notice Internal function used to check whether the investor is in the whitelist or not\n& also checks whether the KYC of investor get expired or not\n@param _investor Address of the investor", + "id": 18233, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "onWhitelist", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18202, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18201, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 18233, + "src": "13252:17:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18200, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13252:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13251:19:47" + }, + "payable": false, + "returnParameters": { + "id": 18205, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18204, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 18233, + "src": "13293:4:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 18203, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "13293:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13292:6:47" + }, + "scope": 18264, + "src": "13231:226:47", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 18262, + "nodeType": "Block", + "src": "13612:174:47", + "statements": [ + { + "assignments": [], + "declarations": [ + { + "constant": false, + "id": 18239, + "name": "_sto", + "nodeType": "VariableDeclaration", + "scope": 18263, + "src": "13622:12:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 18238, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13622:7:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 18240, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "13622:12:47" + }, + { + "expression": { + "argumentTypes": null, + "id": 18250, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "components": [ + null, + { + "argumentTypes": null, + "id": 18241, + "name": "_sto", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18239, + "src": "13647:4:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 18242, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "13644:8:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$_t_address_$", + "typeString": "tuple(,address)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "33", + "id": 18247, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13695:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + { + "argumentTypes": null, + "hexValue": "30", + "id": 18248, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13698:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 18244, + "name": "securityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9442, + "src": "13670:13:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 18243, + "name": "ISecurityToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10038, + "src": "13655:14:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ISecurityToken_$10038_$", + "typeString": "type(contract ISecurityToken)" + } + }, + "id": 18245, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13655:29:47", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ISecurityToken_$10038", + "typeString": "contract ISecurityToken" + } + }, + "id": 18246, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getModule", + "nodeType": "MemberAccess", + "referencedDeclaration": 10000, + "src": "13655:39:47", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_uint8_$_t_uint256_$returns$_t_bytes32_$_t_address_$", + "typeString": "function (uint8,uint256) view external returns (bytes32,address)" + } + }, + "id": 18249, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13655:45:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$", + "typeString": "tuple(bytes32,address)" + } + }, + "src": "13644:56:47", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 18251, + "nodeType": "ExpressionStatement", + "src": "13644:56:47" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 18256, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 18252, + "name": "_sto", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18239, + "src": "13714:4:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 18254, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13730:1:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 18253, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "13722:7:47", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 18255, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13722:10:47", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13714:18:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 18259, + "nodeType": "IfStatement", + "src": "13710:48:47", + "trueBody": { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 18257, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13753:5:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 18237, + "id": 18258, + "nodeType": "Return", + "src": "13746:12:47" + } + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 18260, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13775:4:47", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 18237, + "id": 18261, + "nodeType": "Return", + "src": "13768:11:47" + } + ] + }, + "documentation": "@notice Internal function use to know whether the STO is attached or not", + "id": 18263, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "isSTOAttached", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 18234, + "nodeType": "ParameterList", + "parameters": [], + "src": "13581:2:47" + }, + "payable": false, + "returnParameters": { + "id": 18237, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 18236, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 18263, + "src": "13606:4:47", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 18235, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "13606:4:47", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13605:6:47" + }, + "scope": 18264, + "src": "13559:227:47", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + } + ], + "scope": 18265, + "src": "759:13030:47" + } + ], + "src": "0:13790:47" + }, + "compiler": { + "name": "solc", + "version": "0.4.24+commit.e67f0147.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.1", + "updatedAt": "2018-10-08T12:18:27.781Z" +} \ No newline at end of file diff --git a/CLI/data/SecurityToken1-4-0.json b/CLI/data/SecurityToken1-4-0.json new file mode 100644 index 000000000..59b95a3e4 --- /dev/null +++ b/CLI/data/SecurityToken1-4-0.json @@ -0,0 +1,53469 @@ +{ + "contractName": "SecurityToken", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "investorListed", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "finishedSTOMinting", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "tokenBurner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "tickerRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "securityTokenVersion", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "investors", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "currentCheckpointId", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "granularity", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "MAX_MODULES", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "freeze", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "STO_KEY", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseApproval", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "polyToken", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint8" + }, + { + "name": "", + "type": "uint256" + } + ], + "name": "modules", + "outputs": [ + { + "name": "name", + "type": "bytes32" + }, + { + "name": "moduleAddress", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "polymathRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "checkpointTotalSupply", + "outputs": [ + { + "name": "checkpointId", + "type": "uint256" + }, + { + "name": "value", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "TRANSFERMANAGER_KEY", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "finishedIssuerMinting", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "PERMISSIONMANAGER_KEY", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "moduleRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "CHECKPOINT_KEY", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "securityTokenRegistry", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "tokenDetails", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_addedValue", + "type": "uint256" + } + ], + "name": "increaseApproval", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "investorCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "updateFromRegistry", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "uint256" + } + ], + "name": "checkpointBalances", + "outputs": [ + { + "name": "checkpointId", + "type": "uint256" + }, + { + "name": "value", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_name", + "type": "string" + }, + { + "name": "_symbol", + "type": "string" + }, + { + "name": "_decimals", + "type": "uint8" + }, + { + "name": "_granularity", + "type": "uint256" + }, + { + "name": "_tokenDetails", + "type": "string" + }, + { + "name": "_polymathRegistry", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_type", + "type": "uint8" + }, + { + "indexed": false, + "name": "_name", + "type": "bytes32" + }, + { + "indexed": false, + "name": "_moduleFactory", + "type": "address" + }, + { + "indexed": false, + "name": "_module", + "type": "address" + }, + { + "indexed": false, + "name": "_moduleCost", + "type": "uint256" + }, + { + "indexed": false, + "name": "_budget", + "type": "uint256" + }, + { + "indexed": false, + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "LogModuleAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_oldDetails", + "type": "string" + }, + { + "indexed": false, + "name": "_newDetails", + "type": "string" + } + ], + "name": "LogUpdateTokenDetails", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_oldGranularity", + "type": "uint256" + }, + { + "indexed": false, + "name": "_newGranularity", + "type": "uint256" + } + ], + "name": "LogGranularityChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_type", + "type": "uint8" + }, + { + "indexed": false, + "name": "_module", + "type": "address" + }, + { + "indexed": false, + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "LogModuleRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_moduleType", + "type": "uint8" + }, + { + "indexed": false, + "name": "_module", + "type": "address" + }, + { + "indexed": false, + "name": "_budget", + "type": "uint256" + } + ], + "name": "LogModuleBudgetChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_freeze", + "type": "bool" + }, + { + "indexed": false, + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "LogFreezeTransfers", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_checkpointId", + "type": "uint256" + }, + { + "indexed": false, + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "LogCheckpointCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "LogFinishMintingIssuer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "_timestamp", + "type": "uint256" + } + ], + "name": "LogFinishMintingSTO", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_oldAddress", + "type": "address" + }, + { + "indexed": true, + "name": "_newAddress", + "type": "address" + } + ], + "name": "LogChangeSTRAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "previousOwner", + "type": "address" + } + ], + "name": "OwnershipRenounced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Minted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "_burner", + "type": "address" + }, + { + "indexed": false, + "name": "_value", + "type": "uint256" + } + ], + "name": "Burnt", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "constant": false, + "inputs": [ + { + "name": "_moduleFactory", + "type": "address" + }, + { + "name": "_data", + "type": "bytes" + }, + { + "name": "_maxCost", + "type": "uint256" + }, + { + "name": "_budget", + "type": "uint256" + } + ], + "name": "addModule", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_moduleType", + "type": "uint8" + }, + { + "name": "_moduleIndex", + "type": "uint8" + } + ], + "name": "removeModule", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_moduleType", + "type": "uint8" + }, + { + "name": "_moduleIndex", + "type": "uint256" + } + ], + "name": "getModule", + "outputs": [ + { + "name": "", + "type": "bytes32" + }, + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_moduleType", + "type": "uint8" + }, + { + "name": "_name", + "type": "bytes32" + } + ], + "name": "getModuleByName", + "outputs": [ + { + "name": "", + "type": "bytes32" + }, + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawPoly", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_moduleType", + "type": "uint8" + }, + { + "name": "_moduleIndex", + "type": "uint8" + }, + { + "name": "_budget", + "type": "uint256" + } + ], + "name": "changeModuleBudget", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_newTokenDetails", + "type": "string" + } + ], + "name": "updateTokenDetails", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_granularity", + "type": "uint256" + } + ], + "name": "changeGranularity", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_start", + "type": "uint256" + }, + { + "name": "_iters", + "type": "uint256" + } + ], + "name": "pruneInvestors", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getInvestorsLength", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "freezeTransfers", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "unfreezeTransfers", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "name": "verifyTransfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "finishMintingIssuer", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "finishMintingSTO", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_investor", + "type": "address" + }, + { + "name": "_amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_investors", + "type": "address[]" + }, + { + "name": "_amounts", + "type": "uint256[]" + } + ], + "name": "mintMulti", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_delegate", + "type": "address" + }, + { + "name": "_module", + "type": "address" + }, + { + "name": "_perm", + "type": "bytes32" + } + ], + "name": "checkPermission", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_tokenBurner", + "type": "address" + } + ], + "name": "setTokenBurner", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "createCheckpoint", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_checkpointId", + "type": "uint256" + } + ], + "name": "totalSupplyAt", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_investor", + "type": "address" + }, + { + "name": "_checkpointId", + "type": "uint256" + } + ], + "name": "balanceOfAt", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x6080604052600c805460ff191690556011805460a060020a60ff02191690556014805461ffff191690553480156200003657600080fd5b5060405162004ee538038062004ee58339810160409081528151602080840151928401516060850151608086015160a08701519487018051909796870196939592949190930192829188918891889162000097916003919086019062000635565b508151620000ad90600490602085019062000635565b506005805460ff90921660ff19909216919091179055505060078054600160a060020a03191633179055600160a060020a0381161515620000ed57600080fd5b600c8054600160a060020a039092166101000261010060a860020a031990921691909117905562000126640100000000620002a6810204565b81516200013b90600690602085019062000635565b5050506008555050604080517f7472616e7366657228616464726573732c75696e743235362900000000000000815281519081900360190181207fffffffff00000000000000000000000000000000000000000000000000000000908116600090815260156020818152858320805460ff1990811660019081179092557f7472616e7366657246726f6d28616464726573732c616464726573732c75696e87527f74323536290000000000000000000000000000000000000000000000000000008388015287519687900360250187208616855283835287852080548216831790557f6d696e7428616464726573732c75696e743235362900000000000000000000008752875196879003840187208616855283835287852080548216831790557f6275726e2875696e7432353629000000000000000000000000000000000000008752875196879003600d01909620909416835252929092208054909116909117905550620006da565b600754600160a060020a03163314620002be57600080fd5b600c54604080517fbf40fac1000000000000000000000000000000000000000000000000000000008152602060048201819052600e60248301527f4d6f64756c65526567697374727900000000000000000000000000000000000060448301529151610100909304600160a060020a03169263bf40fac1926064808401939192918290030181600087803b1580156200035657600080fd5b505af11580156200036b573d6000803e3d6000fd5b505050506040513d60208110156200038257600080fd5b5051600d8054600160a060020a031916600160a060020a03928316179055600c54604080517fbf40fac1000000000000000000000000000000000000000000000000000000008152602060048201819052601560248301527f5365637572697479546f6b656e52656769737472790000000000000000000000604483015291516101009093049093169263bf40fac192606480830193928290030181600087803b1580156200043057600080fd5b505af115801562000445573d6000803e3d6000fd5b505050506040513d60208110156200045c57600080fd5b5051600e8054600160a060020a031916600160a060020a03928316178155600c54604080517fbf40fac100000000000000000000000000000000000000000000000000000000815260206004820181905260248201949094527f5469636b65725265676973747279000000000000000000000000000000000000604482015290516101009092049093169263bf40fac19260648083019391928290030181600087803b1580156200050c57600080fd5b505af115801562000521573d6000803e3d6000fd5b505050506040513d60208110156200053857600080fd5b5051600f8054600160a060020a031916600160a060020a03928316179055600c54604080517fbf40fac1000000000000000000000000000000000000000000000000000000008152602060048201819052600960248301527f506f6c79546f6b656e0000000000000000000000000000000000000000000000604483015291516101009093049093169263bf40fac192606480830193928290030181600087803b158015620005e657600080fd5b505af1158015620005fb573d6000803e3d6000fd5b505050506040513d60208110156200061257600080fd5b505160108054600160a060020a031916600160a060020a03909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200067857805160ff1916838001178555620006a8565b82800160010185558215620006a8579182015b82811115620006a85782518255916020019190600101906200068b565b50620006b6929150620006ba565b5090565b620006d791905b80821115620006b65760008155600101620006c1565b90565b6147fb80620006ea6000396000f3006080604052600436106102c65763ffffffff60e060020a6000350416630150246081146102cb57806306fdde03146102e2578063095ea7b31461036c5780630c72a835146103a457806318160ddd146103c55780631b2ae899146103ec5780631bc125f31461040d578063210a8d0e14610422578063219371921461043a57806323b872dd1461044f5780632996f972146104795780632a858126146104aa578063313ce567146104bf57806331c420d4146104ea5780633876e6d3146104ff5780633feb5f2b1461051457806340c10f191461052c57806342966c681461055057806346b65ffd1461056857806346e4959d146105a75780634ee2cd7e146106355780635488cc8014610659578063556f0dc71461066e5780635f1e8c1b146106835780635fcc62771461069857806362a5af3b146106bc5780636604ca6b146106d157806366188463146106e65780636faa22a51461070a57806370a082311461071f578063715018a614610740578063729d20e21461075557806373826a931461077357806377282b70146107cc5780637e8937d9146107e15780638658b8b9146108125780638da5cb5b1461083c57806391415ce91461085157806395d89b4114610866578063981b24d01461087b5780639a4b1d5c146108935780639c3fe721146108bd5780639f45b45c146108d2578063a3f7e26d146108f0578063a8ef4b6614610905578063a9059cbb1461091a578063b0af768b1461093e578063b95459e41461095f578063bcddd64e14610974578063c5bac42114610989578063ce4dbdff146109a4578063d6abe110146109b9578063d73dd623146109ce578063d7e64c00146109f2578063dd62ed3e14610a07578063e3cc65e214610a2e578063f2fde38b14610a43578063f433262f14610a64578063f5efbd2d14610a79578063f8a4cc3314610aac578063fbaa401914610ac4578063ff0b9c9014610ae8575b600080fd5b3480156102d757600080fd5b506102e0610afd565b005b3480156102ee57600080fd5b506102f7610b97565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610331578181015183820152602001610319565b50505050905090810190601f16801561035e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561037857600080fd5b50610390600160a060020a0360043516602435610c25565b604080519115158252519081900360200190f35b3480156103b057600080fd5b50610390600160a060020a0360043516610c8b565b3480156103d157600080fd5b506103da610ca0565b60408051918252519081900360200190f35b3480156103f857600080fd5b506102e060ff60043581169060243516610ca7565b34801561041957600080fd5b506102e0610f47565b34801561042e57600080fd5b506102e0600435610fa2565b34801561044657600080fd5b50610390611052565b34801561045b57600080fd5b50610390600160a060020a0360043581169060243516604435611060565b34801561048557600080fd5b5061048e6110ee565b60408051600160a060020a039092168252519081900360200190f35b3480156104b657600080fd5b5061048e6110fd565b3480156104cb57600080fd5b506104d461110c565b6040805160ff9092168252519081900360200190f35b3480156104f657600080fd5b506102e0611115565b34801561050b57600080fd5b506103da6111ab565b34801561052057600080fd5b5061048e6004356111cf565b34801561053857600080fd5b50610390600160a060020a03600435166024356111f7565b34801561055c57600080fd5b506102e0600435611736565b34801561057457600080fd5b5061058660ff60043516602435611afc565b60408051928352600160a060020a0390911660208301528051918290030190f35b3480156105b357600080fd5b506040805160206004803580820135838102808601850190965280855261039095369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750611b9a9650505050505050565b34801561064157600080fd5b506103da600160a060020a0360043516602435611e9d565b34801561066557600080fd5b506103da611ecf565b34801561067a57600080fd5b506103da611ed5565b34801561068f57600080fd5b506104d4611edb565b3480156106a457600080fd5b506102e060ff60043581169060243516604435611ee0565b3480156106c857600080fd5b506103906123d2565b3480156106dd57600080fd5b506104d46123e2565b3480156106f257600080fd5b50610390600160a060020a03600435166024356123e7565b34801561071657600080fd5b5061048e6124d7565b34801561072b57600080fd5b506103da600160a060020a03600435166124e6565b34801561074c57600080fd5b506102e0612501565b34801561076157600080fd5b5061058660ff60043516602435612562565b34801561077f57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102e09436949293602493928401919081908401838280828437509497506125a69650505050505050565b3480156107d857600080fd5b5061048e6126e9565b3480156107ed57600080fd5b506107f96004356126fd565b6040805192835260208301919091528051918290030190f35b34801561081e57600080fd5b50610390600160a060020a0360043581169060243516604435612729565b34801561084857600080fd5b5061048e6128b0565b34801561085d57600080fd5b506104d46128bf565b34801561087257600080fd5b506102f76128c4565b34801561088757600080fd5b506103da60043561291f565b34801561089f57600080fd5b50610390600160a060020a0360043581169060243516604435612935565b3480156108c957600080fd5b50610390612c81565b3480156108de57600080fd5b5061058660ff60043516602435612c8a565b3480156108fc57600080fd5b506102e0612d8a565b34801561091157600080fd5b506104d4612de3565b34801561092657600080fd5b50610390600160a060020a0360043516602435612de8565b34801561094a57600080fd5b506102e0600160a060020a0360043516612e74565b34801561096b57600080fd5b5061048e612ead565b34801561098057600080fd5b506104d4612ebc565b34801561099557600080fd5b506102e0600435602435612ec1565b3480156109b057600080fd5b5061048e613006565b3480156109c557600080fd5b506102f7613015565b3480156109da57600080fd5b50610390600160a060020a0360043516602435613070565b3480156109fe57600080fd5b506103da613109565b348015610a1357600080fd5b506103da600160a060020a036004358116906024351661310f565b348015610a3a57600080fd5b506103da61313a565b348015610a4f57600080fd5b506102e0600160a060020a0360043516613140565b348015610a7057600080fd5b506102e0613163565b348015610a8557600080fd5b506102e060048035600160a060020a0316906024803590810191013560443560643561348d565b348015610ab857600080fd5b506102e0600435613510565b348015610ad057600080fd5b506107f9600160a060020a036004351660243561361b565b348015610af457600080fd5b506103da613656565b600754600160a060020a03163314610b1457600080fd5b60115460a060020a900460ff1615610b2b57600080fd5b6011805474ff0000000000000000000000000000000000000000191660a060020a90811791829055604080519190920460ff161515815242602082015281517fd057913b88ba41d6281d1ee94831a8a6166afd6b478ea9babb2c02b413f172b3929181900390910190a1565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c1d5780601f10610bf257610100808354040283529160200191610c1d565b820191906000526020600020905b815481529060010190602001808311610c0057829003601f168201915b505050505081565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60176020526000908152604090205460ff1681565b6001545b90565b600754600160a060020a03163314610cbe57600080fd5b60ff80831660009081526016602052604090205490821610610d50576040805160e560020a62461bcd02815260206004820152603960248201527f4d6f64756c6520696e64657820646f65736e277420657869737420617320706560448201527f72207468652063686f6f73656e206d6f64756c65207479706500000000000000606482015290519081900360840190fd5b60ff8083166000908152601660205260408120805491929091908416908110610d7557fe5b6000918252602090912060016002909202010154600160a060020a03161415610e0e576040805160e560020a62461bcd02815260206004820152602860248201527f4d6f64756c6520636f6e747261637420616464726573732073686f756c64206e60448201527f6f74206265203078000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60ff8083166000818152601660205260409020805491927fe69a96f148bcf365cf82241853ecbeb32c5b01500d98bf3d93ee870cd951162c92908516908110610e5357fe5b60009182526020918290206001600290920201015460408051600160a060020a039092168252429282019290925281519081900390910190a260ff8216600090815260166020526040902080546000198101908110610eae57fe5b9060005260206000209060020201601660008460ff1660ff1681526020019081526020016000208260ff16815481101515610ee557fe5b600091825260208083208454600290930201918255600193840154939091018054600160a060020a031916600160a060020a039094169390931790925560ff8416815260169091526040902080546000190190610f42908261467b565b505050565b600754600160a060020a03163314610f5e57600080fd5b6014805461ff0019166101001790556040805142815290517fc3f76bdabdaf2a3983623e5efddd4deb49a4acdca62642d61969164d2a4441259181900360200190a1565b600754600160a060020a03163314610fb957600080fd5b801515611010576040805160e560020a62461bcd02815260206004820152601860248201527f4772616e756c61726974792063616e206e6f7420626520300000000000000000604482015290519081900360640190fd5b600854604080519182526020820183905280517fd13c95c3e8cd875fc20a3da70637bcd9e053e0414035532577769470649507dc9281900390910190a1600855565b601454610100900460ff1681565b600061106d8484846138d3565b611078848484612935565b15156110bc576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b6110c5846139fd565b6110ce836139fd565b6110d9848484613a27565b15156110e457600080fd5b5060019392505050565b601154600160a060020a031681565b600f54600160a060020a031681565b60055460ff1681565b600754600160a060020a0316331461112c57600080fd5b60115460a060020a900460ff16151561114457600080fd5b6011805474ff00000000000000000000000000000000000000001916908190556040805160a060020a90920460ff161515825242602083015280517fd057913b88ba41d6281d1ee94831a8a6166afd6b478ea9babb2c02b413f172b39281900390910190a1565b7f302e302e3100000000000000000000000000000000000000000000000000000081565b600b8054829081106111dd57fe5b600091825260209091200154600160a060020a0316905081565b60006003600182805b60ff808516600090815260166020526040902054908216101561126f578180611265575060ff808516600090815260166020526040902080543392841690811061124657fe5b6000918252602090912060016002909202010154600160a060020a0316145b9150600101611200565b82801561127a575081155b1561139d5760ff8416600314156113365760ff84166000908152601660205260409020541580156112b55750600754600160a060020a031633145b1515611331576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c60448201527f6520697320617474616368656400000000000000000000000000000000000000606482015290519081900360840190fd5b611398565b600754600160a060020a03163314611398576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b61141a565b81151561141a576040805160e560020a62461bcd02815260206004820152602160248201527f53656e646572206973206e6f7420636f7272656374206d6f64756c652074797060448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b856008548181151561142857fe5b06156114a4576040805160e560020a62461bcd02815260206004820152603360248201527f556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732060448201527f61742074686973206772616e756c617269747900000000000000000000000000606482015290519081900360840190fd5b600754600160a060020a03163314156115175760145460ff1615611512576040805160e560020a62461bcd02815260206004820152601e60248201527f4d696e74696e672069732066696e697368656420666f72204973737565720000604482015290519081900360640190fd5b611577565b601454610100900460ff1615611577576040805160e560020a62461bcd02815260206004820152601c60248201527f4d696e74696e672069732066696e697368656420666f722053544f7300000000604482015290519081900360640190fd5b600160a060020a03881615156115fd576040805160e560020a62461bcd02815260206004820152602160248201527f496e766573746f7220616464726573732073686f756c64206e6f74206265203060448201527f7800000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b611609600089896138d3565b61161560008989612935565b1515611659576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b611662886139fd565b61166a613b8c565b60015461167d908863ffffffff613b9b16565b600155600160a060020a0388166000908152602081905260409020546116a9908863ffffffff613b9b16565b600160a060020a038916600081815260208181526040918290209390935580518a8152905191927f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe92918290030190a2604080518881529051600160a060020a038a16916000916000805160206147b08339815191529181900360200190a3506001979650505050505050565b806008548181151561174457fe5b06156117c0576040805160e560020a62461bcd02815260206004820152603360248201527f556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732060448201527f61742074686973206772616e756c617269747900000000000000000000000000606482015290519081900360840190fd5b6117cc336000846138d3565b601154600160a060020a03161515611854576040805160e560020a62461bcd02815260206004820152602c60248201527f546f6b656e204275726e657220636f6e7472616374206164647265737320697360448201527f206e6f7420736574207965740000000000000000000000000000000000000000606482015290519081900360840190fd5b61186033600084612935565b15156118a4576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b33600090815260208190526040902054821115611931576040805160e560020a62461bcd02815260206004820152603960248201527f56616c75652073686f756c64206e6f2062652067726561746572207468616e2060448201527f7468652062616c616e6365206f66206d73672e73656e64657200000000000000606482015290519081900360840190fd5b61193a336139fd565b611942613b8c565b33600090815260208190526040902054611962908363ffffffff613ba816565b336000818152602081815260408083209490945560115484517f9dc29fac0000000000000000000000000000000000000000000000000000000081526004810194909452602484018790529351600160a060020a0390941693639dc29fac93604480820194918390030190829087803b1580156119de57600080fd5b505af11580156119f2573d6000803e3d6000fd5b505050506040513d6020811015611a0857600080fd5b50511515611a86576040805160e560020a62461bcd02815260206004820152602560248201527f546f6b656e206275726e65722070726f63657373206973206e6f742076616c6960448201527f6461746564000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600154611a99908363ffffffff613ba816565b60015560408051838152905133917f919f7e2092ffcc9d09f599be18d8152860b0c054df788a33bc549cdd9d0f15b1919081900360200190a260408051838152905160009133916000805160206147b08339815191529181900360200190a35050565b60ff82166000908152601660205260408120548190811015611b8c5760ff84166000908152601660205260409020805484908110611b3657fe5b6000918252602080832060029092029091015460ff8716835260169091526040909120805485908110611b6557fe5b6000918252602090912060016002909202010154909250600160a060020a03169050611b93565b5060009050805b9250929050565b6000806003600182805b60ff8085166000908152601660205260409020549082161015611c13578180611c09575060ff8085166000908152601660205260409020805433928416908110611bea57fe5b6000918252602090912060016002909202010154600160a060020a0316145b9150600101611ba4565b828015611c1e575081155b15611d415760ff841660031415611cda5760ff8416600090815260166020526040902054158015611c595750600754600160a060020a031633145b1515611cd5576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c60448201527f6520697320617474616368656400000000000000000000000000000000000000606482015290519081900360840190fd5b611d3c565b600754600160a060020a03163314611d3c576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b611dbe565b811515611dbe576040805160e560020a62461bcd02815260206004820152602160248201527f53656e646572206973206e6f7420636f7272656374206d6f64756c652074797060448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8651885114611e3d576040805160e560020a62461bcd02815260206004820152602560248201527f4d69732d6d6174636820696e20746865206c656e677468206f6620746865206160448201527f7272617973000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600094505b8751851015611e8f57611e838886815181101515611e5c57fe5b906020019060200201518887815181101515611e7457fe5b906020019060200201516111f7565b50600190940193611e42565b506001979650505050505050565b600160a060020a0382166000908152601260205260408120611ec89083611ec3866124e6565b613bba565b9392505050565b60095481565b60085481565b601481565b600754600090600160a060020a03163314611efa57600080fd5b60ff84161515611f54576040805160e560020a62461bcd02815260206004820152601a60248201527f4d6f64756c6520747970652063616e6e6f74206265207a65726f000000000000604482015290519081900360640190fd5b60ff80851660009081526016602052604090205490841610611fc0576040805160e560020a62461bcd02815260206004820152601760248201527f496e636f727272656374206d6f64756c6520696e646578000000000000000000604482015290519081900360640190fd5b60105460ff80861660009081526016602052604090208054600160a060020a039093169263dd62ed3e92309291908816908110611ff957fe5b60009182526020808320600160029093020191909101546040805160e060020a63ffffffff8816028152600160a060020a03958616600482015294909116602485015251604480850194929391928390030190829087803b15801561205d57600080fd5b505af1158015612071573d6000803e3d6000fd5b505050506040513d602081101561208757600080fd5b50519050808210156121f45760105460ff80861660009081526016602052604090208054600160a060020a039093169263661884639287169081106120c857fe5b6000918252602090912060016002909202010154600160a060020a03166120f5848663ffffffff613ba816565b6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b15801561214757600080fd5b505af115801561215b573d6000803e3d6000fd5b505050506040513d602081101561217157600080fd5b505115156121ef576040805160e560020a62461bcd02815260206004820152602860248201527f496e73756666696369656e742062616c616e636520746f20646563726561736560448201527f417070726f76616c000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b612350565b60105460ff80861660009081526016602052604090208054600160a060020a039093169263d73dd62392871690811061222957fe5b6000918252602090912060016002909202010154600160a060020a0316612256858563ffffffff613ba816565b6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b1580156122a857600080fd5b505af11580156122bc573d6000803e3d6000fd5b505050506040513d60208110156122d257600080fd5b50511515612350576040805160e560020a62461bcd02815260206004820152602860248201527f496e73756666696369656e742062616c616e636520746f20696e63726561736560448201527f417070726f76616c000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60ff8085166000818152601660205260409020805491927f56e65530d356ea53a7cecc9a37666884b4fe9f05a65df888abd3898548bc15f49290871690811061239557fe5b60009182526020918290206001600290920201015460408051600160a060020a03909216825291810186905281519081900390910190a250505050565b60115460a060020a900460ff1681565b600381565b336000908152600260209081526040808320600160a060020a03861684529091528120548083111561243c57336000908152600260209081526040808320600160a060020a0388168452909152812055612471565b61244c818463ffffffff613ba816565b336000908152600260209081526040808320600160a060020a03891684529091529020555b336000818152600260209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b601054600160a060020a031681565b600160a060020a031660009081526020819052604090205490565b600754600160a060020a0316331461251857600080fd5b600754604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a260078054600160a060020a0319169055565b60166020528160005260406000208181548110151561257d57fe5b600091825260209091206002909102018054600190910154909250600160a060020a0316905082565b600754600160a060020a031633146125bd57600080fd5b6040805181815260068054600260001961010060018416150201909116049282018390527fcef6c04f6d4bada4c1a1fcbb22cadbe4d4fb609cea3788e920628a6186e587659290918491819060208201906060830190869080156126625780601f1061263757610100808354040283529160200191612662565b820191906000526020600020905b81548152906001019060200180831161264557829003601f168201915b5050838103825284518152845160209182019186019080838360005b8381101561269657818101518382015260200161267e565b50505050905090810190601f1680156126c35780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a180516126e59060069060208401906146a7565b5050565b600c546101009004600160a060020a031681565b601380548290811061270b57fe5b60009182526020909120600290910201805460019091015490915082565b6001600090815260166020527f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf49548190151561276857600091506128a8565b5060005b600160005260166020527f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf495460ff821610156128a857600160005260166020527f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf49805460ff83169081106127dc57fe5b6000918252602080832060016002909302019190910154604080517f8658b8b9000000000000000000000000000000000000000000000000000000008152600160a060020a038a8116600483015289811660248301526044820189905291519190921693638658b8b993606480850194919392918390030190829087803b15801561286657600080fd5b505af115801561287a573d6000803e3d6000fd5b505050506040513d602081101561289057600080fd5b5051156128a057600191506128a8565b60010161276c565b509392505050565b600754600160a060020a031681565b600281565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c1d5780601f10610bf257610100808354040283529160200191610c1d565b600061292f601383611ec3610ca0565b92915050565b6000806000806000806000876008548181151561294e57fe5b06156129ca576040805160e560020a62461bcd02815260206004820152603360248201527f556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732060448201527f61742074686973206772616e756c617269747900000000000000000000000000606482015290519081900360840190fd5b60115460a060020a900460ff161515612c6e576000965060156000612a1f6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843750613d65945050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000016815260208101919091526040016000205460ff1615612a5f57600196505b600260005260166020527fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab2885648541515612a9a5760019750612c73565b600095506000945060009350600092505b600260005260166020527fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab28856485460ff84161015612c4c57600260005260166020527fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab2885648805460ff8516908110612b1b57fe5b906000526020600020906002020160010160009054906101000a9004600160a060020a0316600160a060020a0316637915c9e08c8c8c8b6040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a0316815260200183815260200182151515158152602001945050505050602060405180830381600087803b158015612bc857600080fd5b505af1158015612bdc573d6000803e3d6000fd5b505050506040513d6020811015612bf257600080fd5b505191506000826003811115612c0457fe5b1415612c0f57600195505b6002826003811115612c1d57fe5b1415612c2857600194505b6003826003811115612c3657fe5b1415612c4157600193505b600190920191612aab565b83612c645785612c5c5784612c5f565b60005b612c67565b60015b9750612c73565b600097505b505050505050509392505050565b60145460ff1681565b60ff821660009081526016602052604081205481908190811015612d7a575060005b60ff8516600090815260166020526040902054811015612d7a5760ff85166000908152601660205260409020805485919083908110612ce757fe5b60009182526020909120600290910201541415612d725760ff85166000908152601660205260409020805482908110612d1c57fe5b6000918252602080832060029092029091015460ff8816835260169091526040909120805483908110612d4b57fe5b6000918252602090912060016002909202010154909350600160a060020a03169150612d82565b600101612cac565b600092508291505b509250929050565b600754600160a060020a03163314612da157600080fd5b6014805460ff191660011790556040805142815290517f10216e36c4b6dff3d74179d50b938f0f96afc610f073894ca04b4239299165679181900360200190a1565b600181565b6000612df53384846138d3565b612e00338484612935565b1515612e44576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b612e4d336139fd565b612e56836139fd565b612e608383613de6565b1515612e6b57600080fd5b50600192915050565b600754600160a060020a03163314612e8b57600080fd5b60118054600160a060020a031916600160a060020a0392909216919091179055565b600d54600160a060020a031681565b600481565b600754600090600160a060020a03163314612edb57600080fd5b50815b612ef9612ef1848463ffffffff613b9b16565b600b54613eb5565b811015610f4257600b5481108015612f3a5750612f38600b82815481101515612f1e57fe5b600091825260209091200154600160a060020a03166124e6565b155b15612ffe57600060176000600b84815481101515612f5457fe5b600091825260208083209190910154600160a060020a031683528201929092526040019020805460ff1916911515919091179055600b80546000198101908110612f9a57fe5b600091825260209091200154600b8054600160a060020a039092169183908110612fc057fe5b60009182526020909120018054600160a060020a031916600160a060020a0392909216919091179055600b805490612ffc906000198301614725565b505b600101612ede565b600e54600160a060020a031681565b6006805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c1d5780601f10610bf257610100808354040283529160200191610c1d565b336000908152600260209081526040808320600160a060020a03861684529091528120546130a4908363ffffffff613b9b16565b336000818152600260209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600a5481565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b600b5490565b600754600160a060020a0316331461315757600080fd5b61316081613ecb565b50565b600754600160a060020a0316331461317a57600080fd5b600c546040805160e060020a63bf40fac1028152602060048201819052600e60248301527f4d6f64756c65526567697374727900000000000000000000000000000000000060448301529151610100909304600160a060020a03169263bf40fac1926064808401939192918290030181600087803b1580156131fb57600080fd5b505af115801561320f573d6000803e3d6000fd5b505050506040513d602081101561322557600080fd5b5051600d8054600160a060020a031916600160a060020a03928316179055600c546040805160e060020a63bf40fac1028152602060048201819052601560248301527f5365637572697479546f6b656e52656769737472790000000000000000000000604483015291516101009093049093169263bf40fac192606480830193928290030181600087803b1580156132bc57600080fd5b505af11580156132d0573d6000803e3d6000fd5b505050506040513d60208110156132e657600080fd5b5051600e8054600160a060020a031916600160a060020a03928316178155600c546040805160e060020a63bf40fac102815260206004820181905260248201949094527f5469636b65725265676973747279000000000000000000000000000000000000604482015290516101009092049093169263bf40fac19260648083019391928290030181600087803b15801561337f57600080fd5b505af1158015613393573d6000803e3d6000fd5b505050506040513d60208110156133a957600080fd5b5051600f8054600160a060020a031916600160a060020a03928316179055600c546040805160e060020a63bf40fac1028152602060048201819052600960248301527f506f6c79546f6b656e0000000000000000000000000000000000000000000000604483015291516101009093049093169263bf40fac192606480830193928290030181600087803b15801561344057600080fd5b505af1158015613454573d6000803e3d6000fd5b505050506040513d602081101561346a57600080fd5b505160108054600160a060020a031916600160a060020a03909216919091179055565b600754600160a060020a031633146134a457600080fd5b600c5460ff16156134b457600080fd5b600c805460ff19166001179055604080516020601f86018190048102820181019092528481526134ff9187919087908790819084018382808284378201915050505050508484613f3c565b5050600c805460ff19169055505050565b600754600160a060020a0316331461352757600080fd5b601054600754604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561359957600080fd5b505af11580156135ad573d6000803e3d6000fd5b505050506040513d60208110156135c357600080fd5b50511515613160576040805160e560020a62461bcd02815260206004820152601560248201527f496e2d73756666696369656e742062616c616e63650000000000000000000000604482015290519081900360640190fd5b60126020528160005260406000208181548110151561363657fe5b600091825260209091206002909102018054600190910154909250905082565b60006004600182805b60ff80851660009081526016602052604090205490821610156136ce5781806136c4575060ff80851660009081526016602052604090208054339284169081106136a557fe5b6000918252602090912060016002909202010154600160a060020a0316145b915060010161365f565b8280156136d9575081155b156137fc5760ff8416600314156137955760ff84166000908152601660205260409020541580156137145750600754600160a060020a031633145b1515613790576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c60448201527f6520697320617474616368656400000000000000000000000000000000000000606482015290519081900360840190fd5b6137f7565b600754600160a060020a031633146137f7576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b613879565b811515613879576040805160e560020a62461bcd02815260206004820152602160248201527f53656e646572206973206e6f7420636f7272656374206d6f64756c652074797060448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6009546000191161388957600080fd5b60098054600101908190556040805142815290517feb3befa36ea6638fc3379fe62edc59509b81aeca57cfbb0f444b1e72b8ac93fe9181900360200190a260095494505050505090565b8015806138f1575081600160a060020a031683600160a060020a0316145b156138fb57610f42565b613904826124e6565b1580156139195750600160a060020a03821615155b1561393657600a5461393290600163ffffffff613b9b16565b600a555b61393f836124e6565b81141561395e57600a5461395a90600163ffffffff613ba816565b600a555b600160a060020a03821660009081526017602052604090205460ff1615801561398f5750600160a060020a03821615155b15610f4257600b805460018181019092557f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9018054600160a060020a038516600160a060020a031990911681179091556000908152601760205260409020805460ff19169091179055505050565b600160a060020a038116600090815260126020526040902061316090613a22836124e6565b6145b7565b6000600160a060020a0383161515613a3e57600080fd5b600160a060020a038416600090815260208190526040902054821115613a6357600080fd5b600160a060020a0384166000908152600260209081526040808320338452909152902054821115613a9357600080fd5b600160a060020a038416600090815260208190526040902054613abc908363ffffffff613ba816565b600160a060020a038086166000908152602081905260408082209390935590851681522054613af1908363ffffffff613b9b16565b600160a060020a03808516600090815260208181526040808320949094559187168152600282528281203382529091522054613b33908363ffffffff613ba816565b600160a060020a03808616600081815260026020908152604080832033845282529182902094909455805186815290519287169391926000805160206147b0833981519152929181900390910190a35060019392505050565b613b996013613a22610ca0565b565b8181018281101561292f57fe5b600082821115613bb457fe5b50900390565b6000806000806009548611151515613bd157600080fd5b851515613be15760009350613d5b565b86541515613bf157849350613d5b565b85876000815481101515613c0157fe5b600091825260209091206002909102015410613c3f57866000815481101515613c2657fe5b9060005260206000209060020201600101549350613d5b565b8654869088906000198101908110613c5357fe5b9060005260206000209060020201600001541015613c7357849350613d5b565b8654869088906000198101908110613c8757fe5b9060005260206000209060020201600001541415613cb157865487906000198101908110613c2657fe5b8654600093506000190191505b82821115613d38576002828401049050858782815481101515613cdd57fe5b9060005260206000209060020201600001541415613cfd57809150613d38565b858782815481101515613d0c57fe5b9060005260206000209060020201600001541015613d2f57806001019250613d33565b8091505b613cbe565b8682815481101515613d4657fe5b90600052602060002090600202016001015493505b5050509392505050565b60008060006004845110613d7a576004613d7d565b83515b9150600090505b81811015613ddf5780600183030360080260020a8482815181101515613da657fe5b90602001015160f860020a900460f860020a0260f860020a9004028360e060020a90040160e060020a0292508080600101915050613d84565b5050919050565b6000600160a060020a0383161515613dfd57600080fd5b33600090815260208190526040902054821115613e1957600080fd5b33600090815260208190526040902054613e39908363ffffffff613ba816565b3360009081526020819052604080822092909255600160a060020a03851681522054613e6b908363ffffffff613b9b16565b600160a060020a038416600081815260208181526040918290209390935580518581529051919233926000805160206147b08339815191529281900390910190a350600192915050565b6000818310613ec45781611ec8565b5090919050565b600160a060020a0381161515613ee057600080fd5b600754604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360078054600160a060020a031916600160a060020a0392909216919091179055565b600d54604080517fdc659907000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015291516000938493849384938493929092169163dc65990791602480820192869290919082900301818387803b158015613fae57600080fd5b505af1158015613fc2573d6000803e3d6000fd5b5050505088945084600160a060020a03166315dae03e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561400757600080fd5b505af115801561401b573d6000803e3d6000fd5b505050506040513d602081101561403157600080fd5b505160ff81166000908152601660205260409020549094506014116140a0576040805160e560020a62461bcd02815260206004820152601f60248201527f4c696d6974206f66204d4158204d4f44554c4553206973207265616368656400604482015290519081900360640190fd5b84600160a060020a0316637e363ffa6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156140de57600080fd5b505af11580156140f2573d6000803e3d6000fd5b505050506040513d602081101561410857600080fd5b505192508683111561418a576040805160e560020a62461bcd02815260206004820152602e60248201527f4d617820436f737420697320616c77617973206265206772656174657220746860448201527f616e206d6f64756c6520636f7374000000000000000000000000000000000000606482015290519081900360840190fd5b601054604080517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a038c81166004830152602482018790529151919092169163095ea7b39160448083019260209291908290030181600087803b1580156141f957600080fd5b505af115801561420d573d6000803e3d6000fd5b505050506040513d602081101561422357600080fd5b505115156142a1576040805160e560020a62461bcd02815260206004820152602360248201527f4e6f742061626c6520746f20617070726f766520746865206d6f64756c65206360448201527f6f73740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6040517e7743600000000000000000000000000000000000000000000000000000000081526020600482018181528a5160248401528a51600160a060020a0389169362774360938d939283926044019185019080838360005b838110156143125781810151838201526020016142fa565b50505050905090810190601f16801561433f5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561435e57600080fd5b505af1158015614372573d6000803e3d6000fd5b505050506040513d602081101561438857600080fd5b5051601054604080517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a038085166004830152602482018b9052915193955091169163095ea7b3916044808201926020929091908290030181600087803b1580156143fb57600080fd5b505af115801561440f573d6000803e3d6000fd5b505050506040513d602081101561442557600080fd5b5051151561447d576040805160e560020a62461bcd02815260206004820152601e60248201527f4e6f742061626c6520746f20617070726f766520746865206275646765740000604482015290519081900360640190fd5b84600160a060020a03166317d7de7c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156144bb57600080fd5b505af11580156144cf573d6000803e3d6000fd5b505050506040513d60208110156144e557600080fd5b505160ff8516600081815260166020908152604080832081518083018352868152600160a060020a0389811682860181815284546001808201875595895297879020935160029098029093019687559151959092018054600160a060020a031916958316959095179094558151868152908f16928101929092528181019290925260608101879052608081018a90524260a0820152905192935090917fc6c63fb8912a7f464252e66132ad69604864e7520f1bcf0dd77c8d51d810a6519160c0908290030190a2505050505050505050565b60095415156145c5576126e5565b8154151561460c57604080518082019091526009548152602080820183815284546001818101875560008781529390932093516002909102909301928355519101556126e5565b60095482548390600019810190811061462157fe5b906000526020600020906002020160000154141561463e576126e5565b6040805180820190915260095481526020808201928352835460018082018655600095865291909420915160029094029091019283559051910155565b815481835581811115610f4257600202816002028360005260206000209182019101610f429190614749565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106146e857805160ff1916838001178555614715565b82800160010185558215614715579182015b828111156147155782518255916020019190600101906146fa565b50614721929150614775565b5090565b815481835581811115610f4257600083815260209020610f42918101908301614775565b610ca491905b808211156147215760008155600181018054600160a060020a031916905560020161474f565b610ca491905b80821115614721576000815560010161477b56005472616e73666572206973206e6f742076616c69640000000000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a7230582004d9c6c4c665d605118e1c2aac0f5ac1d3d19ac02ffb8e38f82a47dbf4decb8b0029", + "deployedBytecode": "0x6080604052600436106102c65763ffffffff60e060020a6000350416630150246081146102cb57806306fdde03146102e2578063095ea7b31461036c5780630c72a835146103a457806318160ddd146103c55780631b2ae899146103ec5780631bc125f31461040d578063210a8d0e14610422578063219371921461043a57806323b872dd1461044f5780632996f972146104795780632a858126146104aa578063313ce567146104bf57806331c420d4146104ea5780633876e6d3146104ff5780633feb5f2b1461051457806340c10f191461052c57806342966c681461055057806346b65ffd1461056857806346e4959d146105a75780634ee2cd7e146106355780635488cc8014610659578063556f0dc71461066e5780635f1e8c1b146106835780635fcc62771461069857806362a5af3b146106bc5780636604ca6b146106d157806366188463146106e65780636faa22a51461070a57806370a082311461071f578063715018a614610740578063729d20e21461075557806373826a931461077357806377282b70146107cc5780637e8937d9146107e15780638658b8b9146108125780638da5cb5b1461083c57806391415ce91461085157806395d89b4114610866578063981b24d01461087b5780639a4b1d5c146108935780639c3fe721146108bd5780639f45b45c146108d2578063a3f7e26d146108f0578063a8ef4b6614610905578063a9059cbb1461091a578063b0af768b1461093e578063b95459e41461095f578063bcddd64e14610974578063c5bac42114610989578063ce4dbdff146109a4578063d6abe110146109b9578063d73dd623146109ce578063d7e64c00146109f2578063dd62ed3e14610a07578063e3cc65e214610a2e578063f2fde38b14610a43578063f433262f14610a64578063f5efbd2d14610a79578063f8a4cc3314610aac578063fbaa401914610ac4578063ff0b9c9014610ae8575b600080fd5b3480156102d757600080fd5b506102e0610afd565b005b3480156102ee57600080fd5b506102f7610b97565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610331578181015183820152602001610319565b50505050905090810190601f16801561035e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561037857600080fd5b50610390600160a060020a0360043516602435610c25565b604080519115158252519081900360200190f35b3480156103b057600080fd5b50610390600160a060020a0360043516610c8b565b3480156103d157600080fd5b506103da610ca0565b60408051918252519081900360200190f35b3480156103f857600080fd5b506102e060ff60043581169060243516610ca7565b34801561041957600080fd5b506102e0610f47565b34801561042e57600080fd5b506102e0600435610fa2565b34801561044657600080fd5b50610390611052565b34801561045b57600080fd5b50610390600160a060020a0360043581169060243516604435611060565b34801561048557600080fd5b5061048e6110ee565b60408051600160a060020a039092168252519081900360200190f35b3480156104b657600080fd5b5061048e6110fd565b3480156104cb57600080fd5b506104d461110c565b6040805160ff9092168252519081900360200190f35b3480156104f657600080fd5b506102e0611115565b34801561050b57600080fd5b506103da6111ab565b34801561052057600080fd5b5061048e6004356111cf565b34801561053857600080fd5b50610390600160a060020a03600435166024356111f7565b34801561055c57600080fd5b506102e0600435611736565b34801561057457600080fd5b5061058660ff60043516602435611afc565b60408051928352600160a060020a0390911660208301528051918290030190f35b3480156105b357600080fd5b506040805160206004803580820135838102808601850190965280855261039095369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750611b9a9650505050505050565b34801561064157600080fd5b506103da600160a060020a0360043516602435611e9d565b34801561066557600080fd5b506103da611ecf565b34801561067a57600080fd5b506103da611ed5565b34801561068f57600080fd5b506104d4611edb565b3480156106a457600080fd5b506102e060ff60043581169060243516604435611ee0565b3480156106c857600080fd5b506103906123d2565b3480156106dd57600080fd5b506104d46123e2565b3480156106f257600080fd5b50610390600160a060020a03600435166024356123e7565b34801561071657600080fd5b5061048e6124d7565b34801561072b57600080fd5b506103da600160a060020a03600435166124e6565b34801561074c57600080fd5b506102e0612501565b34801561076157600080fd5b5061058660ff60043516602435612562565b34801561077f57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102e09436949293602493928401919081908401838280828437509497506125a69650505050505050565b3480156107d857600080fd5b5061048e6126e9565b3480156107ed57600080fd5b506107f96004356126fd565b6040805192835260208301919091528051918290030190f35b34801561081e57600080fd5b50610390600160a060020a0360043581169060243516604435612729565b34801561084857600080fd5b5061048e6128b0565b34801561085d57600080fd5b506104d46128bf565b34801561087257600080fd5b506102f76128c4565b34801561088757600080fd5b506103da60043561291f565b34801561089f57600080fd5b50610390600160a060020a0360043581169060243516604435612935565b3480156108c957600080fd5b50610390612c81565b3480156108de57600080fd5b5061058660ff60043516602435612c8a565b3480156108fc57600080fd5b506102e0612d8a565b34801561091157600080fd5b506104d4612de3565b34801561092657600080fd5b50610390600160a060020a0360043516602435612de8565b34801561094a57600080fd5b506102e0600160a060020a0360043516612e74565b34801561096b57600080fd5b5061048e612ead565b34801561098057600080fd5b506104d4612ebc565b34801561099557600080fd5b506102e0600435602435612ec1565b3480156109b057600080fd5b5061048e613006565b3480156109c557600080fd5b506102f7613015565b3480156109da57600080fd5b50610390600160a060020a0360043516602435613070565b3480156109fe57600080fd5b506103da613109565b348015610a1357600080fd5b506103da600160a060020a036004358116906024351661310f565b348015610a3a57600080fd5b506103da61313a565b348015610a4f57600080fd5b506102e0600160a060020a0360043516613140565b348015610a7057600080fd5b506102e0613163565b348015610a8557600080fd5b506102e060048035600160a060020a0316906024803590810191013560443560643561348d565b348015610ab857600080fd5b506102e0600435613510565b348015610ad057600080fd5b506107f9600160a060020a036004351660243561361b565b348015610af457600080fd5b506103da613656565b600754600160a060020a03163314610b1457600080fd5b60115460a060020a900460ff1615610b2b57600080fd5b6011805474ff0000000000000000000000000000000000000000191660a060020a90811791829055604080519190920460ff161515815242602082015281517fd057913b88ba41d6281d1ee94831a8a6166afd6b478ea9babb2c02b413f172b3929181900390910190a1565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c1d5780601f10610bf257610100808354040283529160200191610c1d565b820191906000526020600020905b815481529060010190602001808311610c0057829003601f168201915b505050505081565b336000818152600260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60176020526000908152604090205460ff1681565b6001545b90565b600754600160a060020a03163314610cbe57600080fd5b60ff80831660009081526016602052604090205490821610610d50576040805160e560020a62461bcd02815260206004820152603960248201527f4d6f64756c6520696e64657820646f65736e277420657869737420617320706560448201527f72207468652063686f6f73656e206d6f64756c65207479706500000000000000606482015290519081900360840190fd5b60ff8083166000908152601660205260408120805491929091908416908110610d7557fe5b6000918252602090912060016002909202010154600160a060020a03161415610e0e576040805160e560020a62461bcd02815260206004820152602860248201527f4d6f64756c6520636f6e747261637420616464726573732073686f756c64206e60448201527f6f74206265203078000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60ff8083166000818152601660205260409020805491927fe69a96f148bcf365cf82241853ecbeb32c5b01500d98bf3d93ee870cd951162c92908516908110610e5357fe5b60009182526020918290206001600290920201015460408051600160a060020a039092168252429282019290925281519081900390910190a260ff8216600090815260166020526040902080546000198101908110610eae57fe5b9060005260206000209060020201601660008460ff1660ff1681526020019081526020016000208260ff16815481101515610ee557fe5b600091825260208083208454600290930201918255600193840154939091018054600160a060020a031916600160a060020a039094169390931790925560ff8416815260169091526040902080546000190190610f42908261467b565b505050565b600754600160a060020a03163314610f5e57600080fd5b6014805461ff0019166101001790556040805142815290517fc3f76bdabdaf2a3983623e5efddd4deb49a4acdca62642d61969164d2a4441259181900360200190a1565b600754600160a060020a03163314610fb957600080fd5b801515611010576040805160e560020a62461bcd02815260206004820152601860248201527f4772616e756c61726974792063616e206e6f7420626520300000000000000000604482015290519081900360640190fd5b600854604080519182526020820183905280517fd13c95c3e8cd875fc20a3da70637bcd9e053e0414035532577769470649507dc9281900390910190a1600855565b601454610100900460ff1681565b600061106d8484846138d3565b611078848484612935565b15156110bc576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b6110c5846139fd565b6110ce836139fd565b6110d9848484613a27565b15156110e457600080fd5b5060019392505050565b601154600160a060020a031681565b600f54600160a060020a031681565b60055460ff1681565b600754600160a060020a0316331461112c57600080fd5b60115460a060020a900460ff16151561114457600080fd5b6011805474ff00000000000000000000000000000000000000001916908190556040805160a060020a90920460ff161515825242602083015280517fd057913b88ba41d6281d1ee94831a8a6166afd6b478ea9babb2c02b413f172b39281900390910190a1565b7f302e302e3100000000000000000000000000000000000000000000000000000081565b600b8054829081106111dd57fe5b600091825260209091200154600160a060020a0316905081565b60006003600182805b60ff808516600090815260166020526040902054908216101561126f578180611265575060ff808516600090815260166020526040902080543392841690811061124657fe5b6000918252602090912060016002909202010154600160a060020a0316145b9150600101611200565b82801561127a575081155b1561139d5760ff8416600314156113365760ff84166000908152601660205260409020541580156112b55750600754600160a060020a031633145b1515611331576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c60448201527f6520697320617474616368656400000000000000000000000000000000000000606482015290519081900360840190fd5b611398565b600754600160a060020a03163314611398576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b61141a565b81151561141a576040805160e560020a62461bcd02815260206004820152602160248201527f53656e646572206973206e6f7420636f7272656374206d6f64756c652074797060448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b856008548181151561142857fe5b06156114a4576040805160e560020a62461bcd02815260206004820152603360248201527f556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732060448201527f61742074686973206772616e756c617269747900000000000000000000000000606482015290519081900360840190fd5b600754600160a060020a03163314156115175760145460ff1615611512576040805160e560020a62461bcd02815260206004820152601e60248201527f4d696e74696e672069732066696e697368656420666f72204973737565720000604482015290519081900360640190fd5b611577565b601454610100900460ff1615611577576040805160e560020a62461bcd02815260206004820152601c60248201527f4d696e74696e672069732066696e697368656420666f722053544f7300000000604482015290519081900360640190fd5b600160a060020a03881615156115fd576040805160e560020a62461bcd02815260206004820152602160248201527f496e766573746f7220616464726573732073686f756c64206e6f74206265203060448201527f7800000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b611609600089896138d3565b61161560008989612935565b1515611659576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b611662886139fd565b61166a613b8c565b60015461167d908863ffffffff613b9b16565b600155600160a060020a0388166000908152602081905260409020546116a9908863ffffffff613b9b16565b600160a060020a038916600081815260208181526040918290209390935580518a8152905191927f30385c845b448a36257a6a1716e6ad2e1bc2cbe333cde1e69fe849ad6511adfe92918290030190a2604080518881529051600160a060020a038a16916000916000805160206147b08339815191529181900360200190a3506001979650505050505050565b806008548181151561174457fe5b06156117c0576040805160e560020a62461bcd02815260206004820152603360248201527f556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732060448201527f61742074686973206772616e756c617269747900000000000000000000000000606482015290519081900360840190fd5b6117cc336000846138d3565b601154600160a060020a03161515611854576040805160e560020a62461bcd02815260206004820152602c60248201527f546f6b656e204275726e657220636f6e7472616374206164647265737320697360448201527f206e6f7420736574207965740000000000000000000000000000000000000000606482015290519081900360840190fd5b61186033600084612935565b15156118a4576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b33600090815260208190526040902054821115611931576040805160e560020a62461bcd02815260206004820152603960248201527f56616c75652073686f756c64206e6f2062652067726561746572207468616e2060448201527f7468652062616c616e6365206f66206d73672e73656e64657200000000000000606482015290519081900360840190fd5b61193a336139fd565b611942613b8c565b33600090815260208190526040902054611962908363ffffffff613ba816565b336000818152602081815260408083209490945560115484517f9dc29fac0000000000000000000000000000000000000000000000000000000081526004810194909452602484018790529351600160a060020a0390941693639dc29fac93604480820194918390030190829087803b1580156119de57600080fd5b505af11580156119f2573d6000803e3d6000fd5b505050506040513d6020811015611a0857600080fd5b50511515611a86576040805160e560020a62461bcd02815260206004820152602560248201527f546f6b656e206275726e65722070726f63657373206973206e6f742076616c6960448201527f6461746564000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600154611a99908363ffffffff613ba816565b60015560408051838152905133917f919f7e2092ffcc9d09f599be18d8152860b0c054df788a33bc549cdd9d0f15b1919081900360200190a260408051838152905160009133916000805160206147b08339815191529181900360200190a35050565b60ff82166000908152601660205260408120548190811015611b8c5760ff84166000908152601660205260409020805484908110611b3657fe5b6000918252602080832060029092029091015460ff8716835260169091526040909120805485908110611b6557fe5b6000918252602090912060016002909202010154909250600160a060020a03169050611b93565b5060009050805b9250929050565b6000806003600182805b60ff8085166000908152601660205260409020549082161015611c13578180611c09575060ff8085166000908152601660205260409020805433928416908110611bea57fe5b6000918252602090912060016002909202010154600160a060020a0316145b9150600101611ba4565b828015611c1e575081155b15611d415760ff841660031415611cda5760ff8416600090815260166020526040902054158015611c595750600754600160a060020a031633145b1515611cd5576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c60448201527f6520697320617474616368656400000000000000000000000000000000000000606482015290519081900360840190fd5b611d3c565b600754600160a060020a03163314611d3c576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b611dbe565b811515611dbe576040805160e560020a62461bcd02815260206004820152602160248201527f53656e646572206973206e6f7420636f7272656374206d6f64756c652074797060448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8651885114611e3d576040805160e560020a62461bcd02815260206004820152602560248201527f4d69732d6d6174636820696e20746865206c656e677468206f6620746865206160448201527f7272617973000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600094505b8751851015611e8f57611e838886815181101515611e5c57fe5b906020019060200201518887815181101515611e7457fe5b906020019060200201516111f7565b50600190940193611e42565b506001979650505050505050565b600160a060020a0382166000908152601260205260408120611ec89083611ec3866124e6565b613bba565b9392505050565b60095481565b60085481565b601481565b600754600090600160a060020a03163314611efa57600080fd5b60ff84161515611f54576040805160e560020a62461bcd02815260206004820152601a60248201527f4d6f64756c6520747970652063616e6e6f74206265207a65726f000000000000604482015290519081900360640190fd5b60ff80851660009081526016602052604090205490841610611fc0576040805160e560020a62461bcd02815260206004820152601760248201527f496e636f727272656374206d6f64756c6520696e646578000000000000000000604482015290519081900360640190fd5b60105460ff80861660009081526016602052604090208054600160a060020a039093169263dd62ed3e92309291908816908110611ff957fe5b60009182526020808320600160029093020191909101546040805160e060020a63ffffffff8816028152600160a060020a03958616600482015294909116602485015251604480850194929391928390030190829087803b15801561205d57600080fd5b505af1158015612071573d6000803e3d6000fd5b505050506040513d602081101561208757600080fd5b50519050808210156121f45760105460ff80861660009081526016602052604090208054600160a060020a039093169263661884639287169081106120c857fe5b6000918252602090912060016002909202010154600160a060020a03166120f5848663ffffffff613ba816565b6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b15801561214757600080fd5b505af115801561215b573d6000803e3d6000fd5b505050506040513d602081101561217157600080fd5b505115156121ef576040805160e560020a62461bcd02815260206004820152602860248201527f496e73756666696369656e742062616c616e636520746f20646563726561736560448201527f417070726f76616c000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b612350565b60105460ff80861660009081526016602052604090208054600160a060020a039093169263d73dd62392871690811061222957fe5b6000918252602090912060016002909202010154600160a060020a0316612256858563ffffffff613ba816565b6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b1580156122a857600080fd5b505af11580156122bc573d6000803e3d6000fd5b505050506040513d60208110156122d257600080fd5b50511515612350576040805160e560020a62461bcd02815260206004820152602860248201527f496e73756666696369656e742062616c616e636520746f20696e63726561736560448201527f417070726f76616c000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60ff8085166000818152601660205260409020805491927f56e65530d356ea53a7cecc9a37666884b4fe9f05a65df888abd3898548bc15f49290871690811061239557fe5b60009182526020918290206001600290920201015460408051600160a060020a03909216825291810186905281519081900390910190a250505050565b60115460a060020a900460ff1681565b600381565b336000908152600260209081526040808320600160a060020a03861684529091528120548083111561243c57336000908152600260209081526040808320600160a060020a0388168452909152812055612471565b61244c818463ffffffff613ba816565b336000908152600260209081526040808320600160a060020a03891684529091529020555b336000818152600260209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b601054600160a060020a031681565b600160a060020a031660009081526020819052604090205490565b600754600160a060020a0316331461251857600080fd5b600754604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a260078054600160a060020a0319169055565b60166020528160005260406000208181548110151561257d57fe5b600091825260209091206002909102018054600190910154909250600160a060020a0316905082565b600754600160a060020a031633146125bd57600080fd5b6040805181815260068054600260001961010060018416150201909116049282018390527fcef6c04f6d4bada4c1a1fcbb22cadbe4d4fb609cea3788e920628a6186e587659290918491819060208201906060830190869080156126625780601f1061263757610100808354040283529160200191612662565b820191906000526020600020905b81548152906001019060200180831161264557829003601f168201915b5050838103825284518152845160209182019186019080838360005b8381101561269657818101518382015260200161267e565b50505050905090810190601f1680156126c35780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a180516126e59060069060208401906146a7565b5050565b600c546101009004600160a060020a031681565b601380548290811061270b57fe5b60009182526020909120600290910201805460019091015490915082565b6001600090815260166020527f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf49548190151561276857600091506128a8565b5060005b600160005260166020527f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf495460ff821610156128a857600160005260166020527f4c4dc693d7db52f85fe052106f4b4b920e78e8ef37dee82878a60ab8585faf49805460ff83169081106127dc57fe5b6000918252602080832060016002909302019190910154604080517f8658b8b9000000000000000000000000000000000000000000000000000000008152600160a060020a038a8116600483015289811660248301526044820189905291519190921693638658b8b993606480850194919392918390030190829087803b15801561286657600080fd5b505af115801561287a573d6000803e3d6000fd5b505050506040513d602081101561289057600080fd5b5051156128a057600191506128a8565b60010161276c565b509392505050565b600754600160a060020a031681565b600281565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c1d5780601f10610bf257610100808354040283529160200191610c1d565b600061292f601383611ec3610ca0565b92915050565b6000806000806000806000876008548181151561294e57fe5b06156129ca576040805160e560020a62461bcd02815260206004820152603360248201527f556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732060448201527f61742074686973206772616e756c617269747900000000000000000000000000606482015290519081900360840190fd5b60115460a060020a900460ff161515612c6e576000965060156000612a1f6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843750613d65945050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000016815260208101919091526040016000205460ff1615612a5f57600196505b600260005260166020527fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab2885648541515612a9a5760019750612c73565b600095506000945060009350600092505b600260005260166020527fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab28856485460ff84161015612c4c57600260005260166020527fcaff291fe014adc6b72a172705750b4cabe8f8667664d2924a166caab2885648805460ff8516908110612b1b57fe5b906000526020600020906002020160010160009054906101000a9004600160a060020a0316600160a060020a0316637915c9e08c8c8c8b6040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a0316815260200183815260200182151515158152602001945050505050602060405180830381600087803b158015612bc857600080fd5b505af1158015612bdc573d6000803e3d6000fd5b505050506040513d6020811015612bf257600080fd5b505191506000826003811115612c0457fe5b1415612c0f57600195505b6002826003811115612c1d57fe5b1415612c2857600194505b6003826003811115612c3657fe5b1415612c4157600193505b600190920191612aab565b83612c645785612c5c5784612c5f565b60005b612c67565b60015b9750612c73565b600097505b505050505050509392505050565b60145460ff1681565b60ff821660009081526016602052604081205481908190811015612d7a575060005b60ff8516600090815260166020526040902054811015612d7a5760ff85166000908152601660205260409020805485919083908110612ce757fe5b60009182526020909120600290910201541415612d725760ff85166000908152601660205260409020805482908110612d1c57fe5b6000918252602080832060029092029091015460ff8816835260169091526040909120805483908110612d4b57fe5b6000918252602090912060016002909202010154909350600160a060020a03169150612d82565b600101612cac565b600092508291505b509250929050565b600754600160a060020a03163314612da157600080fd5b6014805460ff191660011790556040805142815290517f10216e36c4b6dff3d74179d50b938f0f96afc610f073894ca04b4239299165679181900360200190a1565b600181565b6000612df53384846138d3565b612e00338484612935565b1515612e44576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614790833981519152604482015290519081900360640190fd5b612e4d336139fd565b612e56836139fd565b612e608383613de6565b1515612e6b57600080fd5b50600192915050565b600754600160a060020a03163314612e8b57600080fd5b60118054600160a060020a031916600160a060020a0392909216919091179055565b600d54600160a060020a031681565b600481565b600754600090600160a060020a03163314612edb57600080fd5b50815b612ef9612ef1848463ffffffff613b9b16565b600b54613eb5565b811015610f4257600b5481108015612f3a5750612f38600b82815481101515612f1e57fe5b600091825260209091200154600160a060020a03166124e6565b155b15612ffe57600060176000600b84815481101515612f5457fe5b600091825260208083209190910154600160a060020a031683528201929092526040019020805460ff1916911515919091179055600b80546000198101908110612f9a57fe5b600091825260209091200154600b8054600160a060020a039092169183908110612fc057fe5b60009182526020909120018054600160a060020a031916600160a060020a0392909216919091179055600b805490612ffc906000198301614725565b505b600101612ede565b600e54600160a060020a031681565b6006805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610c1d5780601f10610bf257610100808354040283529160200191610c1d565b336000908152600260209081526040808320600160a060020a03861684529091528120546130a4908363ffffffff613b9b16565b336000818152600260209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600a5481565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b600b5490565b600754600160a060020a0316331461315757600080fd5b61316081613ecb565b50565b600754600160a060020a0316331461317a57600080fd5b600c546040805160e060020a63bf40fac1028152602060048201819052600e60248301527f4d6f64756c65526567697374727900000000000000000000000000000000000060448301529151610100909304600160a060020a03169263bf40fac1926064808401939192918290030181600087803b1580156131fb57600080fd5b505af115801561320f573d6000803e3d6000fd5b505050506040513d602081101561322557600080fd5b5051600d8054600160a060020a031916600160a060020a03928316179055600c546040805160e060020a63bf40fac1028152602060048201819052601560248301527f5365637572697479546f6b656e52656769737472790000000000000000000000604483015291516101009093049093169263bf40fac192606480830193928290030181600087803b1580156132bc57600080fd5b505af11580156132d0573d6000803e3d6000fd5b505050506040513d60208110156132e657600080fd5b5051600e8054600160a060020a031916600160a060020a03928316178155600c546040805160e060020a63bf40fac102815260206004820181905260248201949094527f5469636b65725265676973747279000000000000000000000000000000000000604482015290516101009092049093169263bf40fac19260648083019391928290030181600087803b15801561337f57600080fd5b505af1158015613393573d6000803e3d6000fd5b505050506040513d60208110156133a957600080fd5b5051600f8054600160a060020a031916600160a060020a03928316179055600c546040805160e060020a63bf40fac1028152602060048201819052600960248301527f506f6c79546f6b656e0000000000000000000000000000000000000000000000604483015291516101009093049093169263bf40fac192606480830193928290030181600087803b15801561344057600080fd5b505af1158015613454573d6000803e3d6000fd5b505050506040513d602081101561346a57600080fd5b505160108054600160a060020a031916600160a060020a03909216919091179055565b600754600160a060020a031633146134a457600080fd5b600c5460ff16156134b457600080fd5b600c805460ff19166001179055604080516020601f86018190048102820181019092528481526134ff9187919087908790819084018382808284378201915050505050508484613f3c565b5050600c805460ff19169055505050565b600754600160a060020a0316331461352757600080fd5b601054600754604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561359957600080fd5b505af11580156135ad573d6000803e3d6000fd5b505050506040513d60208110156135c357600080fd5b50511515613160576040805160e560020a62461bcd02815260206004820152601560248201527f496e2d73756666696369656e742062616c616e63650000000000000000000000604482015290519081900360640190fd5b60126020528160005260406000208181548110151561363657fe5b600091825260209091206002909102018054600190910154909250905082565b60006004600182805b60ff80851660009081526016602052604090205490821610156136ce5781806136c4575060ff80851660009081526016602052604090208054339284169081106136a557fe5b6000918252602090912060016002909202010154600160a060020a0316145b915060010161365f565b8280156136d9575081155b156137fc5760ff8416600314156137955760ff84166000908152601660205260409020541580156137145750600754600160a060020a031633145b1515613790576040805160e560020a62461bcd02815260206004820152602d60248201527f53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c60448201527f6520697320617474616368656400000000000000000000000000000000000000606482015290519081900360840190fd5b6137f7565b600754600160a060020a031633146137f7576040805160e560020a62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b613879565b811515613879576040805160e560020a62461bcd02815260206004820152602160248201527f53656e646572206973206e6f7420636f7272656374206d6f64756c652074797060448201527f6500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6009546000191161388957600080fd5b60098054600101908190556040805142815290517feb3befa36ea6638fc3379fe62edc59509b81aeca57cfbb0f444b1e72b8ac93fe9181900360200190a260095494505050505090565b8015806138f1575081600160a060020a031683600160a060020a0316145b156138fb57610f42565b613904826124e6565b1580156139195750600160a060020a03821615155b1561393657600a5461393290600163ffffffff613b9b16565b600a555b61393f836124e6565b81141561395e57600a5461395a90600163ffffffff613ba816565b600a555b600160a060020a03821660009081526017602052604090205460ff1615801561398f5750600160a060020a03821615155b15610f4257600b805460018181019092557f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9018054600160a060020a038516600160a060020a031990911681179091556000908152601760205260409020805460ff19169091179055505050565b600160a060020a038116600090815260126020526040902061316090613a22836124e6565b6145b7565b6000600160a060020a0383161515613a3e57600080fd5b600160a060020a038416600090815260208190526040902054821115613a6357600080fd5b600160a060020a0384166000908152600260209081526040808320338452909152902054821115613a9357600080fd5b600160a060020a038416600090815260208190526040902054613abc908363ffffffff613ba816565b600160a060020a038086166000908152602081905260408082209390935590851681522054613af1908363ffffffff613b9b16565b600160a060020a03808516600090815260208181526040808320949094559187168152600282528281203382529091522054613b33908363ffffffff613ba816565b600160a060020a03808616600081815260026020908152604080832033845282529182902094909455805186815290519287169391926000805160206147b0833981519152929181900390910190a35060019392505050565b613b996013613a22610ca0565b565b8181018281101561292f57fe5b600082821115613bb457fe5b50900390565b6000806000806009548611151515613bd157600080fd5b851515613be15760009350613d5b565b86541515613bf157849350613d5b565b85876000815481101515613c0157fe5b600091825260209091206002909102015410613c3f57866000815481101515613c2657fe5b9060005260206000209060020201600101549350613d5b565b8654869088906000198101908110613c5357fe5b9060005260206000209060020201600001541015613c7357849350613d5b565b8654869088906000198101908110613c8757fe5b9060005260206000209060020201600001541415613cb157865487906000198101908110613c2657fe5b8654600093506000190191505b82821115613d38576002828401049050858782815481101515613cdd57fe5b9060005260206000209060020201600001541415613cfd57809150613d38565b858782815481101515613d0c57fe5b9060005260206000209060020201600001541015613d2f57806001019250613d33565b8091505b613cbe565b8682815481101515613d4657fe5b90600052602060002090600202016001015493505b5050509392505050565b60008060006004845110613d7a576004613d7d565b83515b9150600090505b81811015613ddf5780600183030360080260020a8482815181101515613da657fe5b90602001015160f860020a900460f860020a0260f860020a9004028360e060020a90040160e060020a0292508080600101915050613d84565b5050919050565b6000600160a060020a0383161515613dfd57600080fd5b33600090815260208190526040902054821115613e1957600080fd5b33600090815260208190526040902054613e39908363ffffffff613ba816565b3360009081526020819052604080822092909255600160a060020a03851681522054613e6b908363ffffffff613b9b16565b600160a060020a038416600081815260208181526040918290209390935580518581529051919233926000805160206147b08339815191529281900390910190a350600192915050565b6000818310613ec45781611ec8565b5090919050565b600160a060020a0381161515613ee057600080fd5b600754604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360078054600160a060020a031916600160a060020a0392909216919091179055565b600d54604080517fdc659907000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015291516000938493849384938493929092169163dc65990791602480820192869290919082900301818387803b158015613fae57600080fd5b505af1158015613fc2573d6000803e3d6000fd5b5050505088945084600160a060020a03166315dae03e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561400757600080fd5b505af115801561401b573d6000803e3d6000fd5b505050506040513d602081101561403157600080fd5b505160ff81166000908152601660205260409020549094506014116140a0576040805160e560020a62461bcd02815260206004820152601f60248201527f4c696d6974206f66204d4158204d4f44554c4553206973207265616368656400604482015290519081900360640190fd5b84600160a060020a0316637e363ffa6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156140de57600080fd5b505af11580156140f2573d6000803e3d6000fd5b505050506040513d602081101561410857600080fd5b505192508683111561418a576040805160e560020a62461bcd02815260206004820152602e60248201527f4d617820436f737420697320616c77617973206265206772656174657220746860448201527f616e206d6f64756c6520636f7374000000000000000000000000000000000000606482015290519081900360840190fd5b601054604080517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a038c81166004830152602482018790529151919092169163095ea7b39160448083019260209291908290030181600087803b1580156141f957600080fd5b505af115801561420d573d6000803e3d6000fd5b505050506040513d602081101561422357600080fd5b505115156142a1576040805160e560020a62461bcd02815260206004820152602360248201527f4e6f742061626c6520746f20617070726f766520746865206d6f64756c65206360448201527f6f73740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6040517e7743600000000000000000000000000000000000000000000000000000000081526020600482018181528a5160248401528a51600160a060020a0389169362774360938d939283926044019185019080838360005b838110156143125781810151838201526020016142fa565b50505050905090810190601f16801561433f5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561435e57600080fd5b505af1158015614372573d6000803e3d6000fd5b505050506040513d602081101561438857600080fd5b5051601054604080517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a038085166004830152602482018b9052915193955091169163095ea7b3916044808201926020929091908290030181600087803b1580156143fb57600080fd5b505af115801561440f573d6000803e3d6000fd5b505050506040513d602081101561442557600080fd5b5051151561447d576040805160e560020a62461bcd02815260206004820152601e60248201527f4e6f742061626c6520746f20617070726f766520746865206275646765740000604482015290519081900360640190fd5b84600160a060020a03166317d7de7c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156144bb57600080fd5b505af11580156144cf573d6000803e3d6000fd5b505050506040513d60208110156144e557600080fd5b505160ff8516600081815260166020908152604080832081518083018352868152600160a060020a0389811682860181815284546001808201875595895297879020935160029098029093019687559151959092018054600160a060020a031916958316959095179094558151868152908f16928101929092528181019290925260608101879052608081018a90524260a0820152905192935090917fc6c63fb8912a7f464252e66132ad69604864e7520f1bcf0dd77c8d51d810a6519160c0908290030190a2505050505050505050565b60095415156145c5576126e5565b8154151561460c57604080518082019091526009548152602080820183815284546001818101875560008781529390932093516002909102909301928355519101556126e5565b60095482548390600019810190811061462157fe5b906000526020600020906002020160000154141561463e576126e5565b6040805180820190915260095481526020808201928352835460018082018655600095865291909420915160029094029091019283559051910155565b815481835581811115610f4257600202816002028360005260206000209182019101610f429190614749565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106146e857805160ff1916838001178555614715565b82800160010185558215614715579182015b828111156147155782518255916020019190600101906146fa565b50614721929150614775565b5090565b815481835581811115610f4257600083815260209020610f42918101908301614775565b610ca491905b808211156147215760008155600181018054600160a060020a031916905560020161474f565b610ca491905b80821115614721576000815560010161477b56005472616e73666572206973206e6f742076616c69640000000000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a7230582004d9c6c4c665d605118e1c2aac0f5ac1d3d19ac02ffb8e38f82a47dbf4decb8b0029", + "sourceMap": "928:26908:59:-;;;321:35:61;;;-1:-1:-1;;321:35:61;;;1223:26:59;;;-1:-1:-1;;;;;;1223:26:59;;;;1618:41;;-1:-1:-1;;1665:38:59;;;5344:770;5:2:-1;;;;30:1;27;20:12;5:2;5344:770:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;463:12:66;;5344:770:59;;;;;;;;;;;;;;;;;;;;;;;463:12:66;;:4;;:12;;;;;:::i;:::-;-1:-1:-1;481:16:66;;;;:6;;:16;;;;;:::i;:::-;-1:-1:-1;503:8:66;:20;;;;;;-1:-1:-1;;503:20:66;;;;;;;;;-1:-1:-1;;567:5:64;:18;;-1:-1:-1;;;;;;567:18:64;575:10;567:18;;;-1:-1:-1;;;;;412:31:5;;;;404:40;;;;;;454:16;:36;;-1:-1:-1;;;;;454:36:5;;;;;-1:-1:-1;;;;;;454:36:5;;;;;;;;;5689:20:59;:18;;;;:20;:::i;:::-;5719:28;;;;:12;;:28;;;;;:::i;:::-;-1:-1:-1;;;5757:11:59;:26;-1:-1:-1;;5818:38:59;;;;;;;;;;;;;;;;5793:65;;;;;;;;:17;:65;;;;;;;:72;;-1:-1:-1;;5793:72:59;;;5861:4;5793:72;;;;;;5900:50;;;;;;;;;;;;;;;;;;5875:77;;;;;;;;;;:84;;;;;;;;5994:34;;;;;;;;;;;;;5969:61;;;;;;;;;;:68;;;;;;;;6072:26;;;;;;;;;;;;;;6047:53;;;;;;;;;;:60;;;;;;;;;;-1:-1:-1;928:26908:59;;503:418:5;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;594:16:5;;577:63;;;;;;;;;;;;;;;;;;;;;;;;;594:16;;;;-1:-1:-1;;;;;594:16:5;;577:45;;:63;;;;;;;;;;;;;-1:-1:-1;594:16:5;577:63;;;5:2:-1;;;;30:1;27;20:12;5:2;577:63:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;577:63:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;577:63:5;560:14;:80;;-1:-1:-1;;;;;;560:80:5;-1:-1:-1;;;;;560:80:5;;;;;;691:16;;674:70;;;;;;577:63;674:70;;;;;;;;;;;;;;;;;;560:80;691:16;;;;;;;674:45;;:70;;;;;577:63;674:70;;;;;-1:-1:-1;691:16:5;674:70;;;5:2:-1;;;;30:1;27;20:12;5:2;674:70:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;674:70:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;674:70:5;650:21;:94;;-1:-1:-1;;;;;;650:94:5;-1:-1:-1;;;;;650:94:5;;;;;;788:16;;771:63;;;;;;674:70;771:63;;;;;;;;;;;;;;;;;;;;650:94;788:16;;;;;;;771:45;;:63;;;;;674:70;;771:63;;;;;-1:-1:-1;788:16:5;771:63;;;5:2:-1;;;;30:1;27;20:12;5:2;771:63:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;771:63:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;771:63:5;754:14;:80;;-1:-1:-1;;;;;;754:80:5;-1:-1:-1;;;;;754:80:5;;;;;;873:16;;856:58;;;;;;771:63;856:58;;;;;;;;;;;;;;;;;;754:80;873:16;;;;;;;856:45;;:58;;;;;771:63;856:58;;;;;-1:-1:-1;873:16:5;856:58;;;5:2:-1;;;;30:1;27;20:12;5:2;856:58:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;856:58:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;856:58:5;844:9;:70;;-1:-1:-1;;;;;;844:70:5;-1:-1:-1;;;;;844:70:5;;;;;;;;;503:418::o;928:26908:59:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;928:26908:59;;;-1:-1:-1;928:26908:59;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;", + "deployedSourceMap": "928:26908:59:-;;;;;;;;;-1:-1:-1;;;928:26908:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15391:146;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15391:146:59;;;;;;319:18:66;;8:9:-1;5:2;;;30:1;27;20:12;5:2;319:18:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;319:18:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1829:188:69;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1829:188:69;-1:-1:-1;;;;;1829:188:69;;;;;;;;;;;;;;;;;;;;;;;;;1902:47:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1902:47:59;-1:-1:-1;;;;;1902:47:59;;;;;371:83:65;;8:9:-1;5:2;;;30:1;27;20:12;5:2;371:83:65;;;;;;;;;;;;;;;;;;;;8909:729:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;8909:729:59;;;;;;;;;;;;20378:126;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20378:126:59;;;;13116:236;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;13116:236:59;;;;;1665:38;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1665:38:59;;;;18189:388;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;18189:388:59;-1:-1:-1;;;;;18189:388:59;;;;;;;;;;;;1145:31;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1145:31:59;;;;;;;;-1:-1:-1;;;;;1145:31:59;;;;;;;;;;;;;;281:29:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;281:29:5;;;;365:21:66;;8:9:-1;5:2;;;30:1;27;20:12;5:2;365:21:66;;;;;;;;;;;;;;;;;;;;;;;15602:148:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15602:148:59;;;;1042:54;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1042:54:59;;;;622:26:19;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;622:26:19;;;;;20865:704:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;20865:704:59;-1:-1:-1;;;;;20865:704:59;;;;;;;23749:993;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;23749:993:59;;;;;9907:373;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9907:373:59;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9907:373:59;;;;;;;;;;;;;;;;;22025:355;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;22025:355:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;22025:355:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22025:355:59;;;;-1:-1:-1;22025:355:59;-1:-1:-1;22025:355:59;;-1:-1:-1;22025:355:59;;;;;;;;;-1:-1:-1;22025:355:59;;-1:-1:-1;22025:355:59;;-1:-1:-1;;;;;;;22025:355:59;27639:194;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;27639:194:59;-1:-1:-1;;;;;27639:194:59;;;;;;;471:34:19;;8:9:-1;5:2;;;30:1;27;20:12;5:2;471:34:19;;;;403:26;;8:9:-1;5:2;;;30:1;27;20:12;5:2;403:26:19;;;;1857:38:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1857:38:59;;;;11751:936;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;11751:936:59;;;;;;;;;;;;;;1223:26;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1223:26:59;;;;318:33:19;;8:9:-1;5:2;;;30:1;27;20:12;5:2;318:33:19;;;;3701:425:69;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;3701:425:69;-1:-1:-1;;;;;3701:425:69;;;;;;;316:24:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;316:24:5;;;;1131:99:65;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1131:99:65;-1:-1:-1;;;;;1131:99:65;;;;;827:111:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;827:111:64;;;;1804:46:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1804:46:59;;;;;;;;;12797:186;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;12797:186:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12797:186:59;;-1:-1:-1;12797:186:59;;-1:-1:-1;;;;;;;12797:186:59;167:31:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;167:31:5;;;;1570:41:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1570:41:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;22864:463;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;22864:463:59;-1:-1:-1;;;;;22864:463:59;;;;;;;;;;;;238:20:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;238:20:64;;;;267:45:19;;8:9:-1;5:2;;;30:1;27;20:12;5:2;267:45:19;;;;341:20:66;;8:9:-1;5:2;;;30:1;27;20:12;5:2;341:20:66;;;;25725:162:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;25725:162:59;;;;;18861:1214;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;18861:1214:59;-1:-1:-1;;;;;18861:1214:59;;;;;;;;;;;;1618:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1618:41:59;;;;10567:578;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;10567:578:59;;;;;;;;;20160:135;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20160:135:59;;;;214:47:19;;8:9:-1;5:2;;;30:1;27;20:12;5:2;214:47:19;;;;17586:373:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;17586:373:59;-1:-1:-1;;;;;17586:373:59;;;;;;;23497:120;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;23497:120:59;-1:-1:-1;;;;;23497:120:59;;;;;204:29:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;204:29:5;;;;357:40:19;;8:9:-1;5:2;;;30:1;27;20:12;5:2;357:40:19;;;;14603:429:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;14603:429:59;;;;;;;239:36:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;239:36:5;;;;303:26:17;;8:9:-1;5:2;;;30:1;27;20:12;5:2;303:26:17;;;;2946:293:69;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2946:293:69;-1:-1:-1;;;;;2946:293:69;;;;;;;558:28:19;;8:9:-1;5:2;;;30:1;27;20:12;5:2;558:28:19;;;;2336:153:69;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;2336:153:69;-1:-1:-1;;;;;2336:153:69;;;;;;;;;;15230:99:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15230:99:59;;;;1100:103:64;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1100:103:64;-1:-1:-1;;;;;1100:103:64;;;;;503:418:5;;8:9:-1;5:2;;;30:1;27;20:12;5:2;503:418:5;;;;6491:230:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;6491:230:59;;;;-1:-1:-1;;;;;6491:230:59;;;;;;;;;;;;;;;;;11404:148;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;11404:148:59;;;;;1505:59;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;1505:59:59;-1:-1:-1;;;;;1505:59:59;;;;;;;25272:295;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25272:295:59;;;;15391:146;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;15454:6:59;;-1:-1:-1;15454:6:59;;;;15453:7;15445:16;;;;;;15471:6;:13;;-1:-1:-1;;15471:13:59;-1:-1:-1;;;15471:13:59;;;;;;;15499:31;;;15518:6;;;;15471:13;15518:6;15499:31;;;;15526:3;15499:31;;;;;;;;;;;;;;;;;15391:146::o;319:18:66:-;;;;;;;;;;;;;;;-1:-1:-1;;319:18:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1829:188:69:-;1916:10;1896:4;1908:19;;;:7;:19;;;;;;;;-1:-1:-1;;;;;1908:29:69;;;;;;;;;;;:38;;;1957;;;;;;;1896:4;;1908:29;;1916:10;;1957:38;;;;;;;;-1:-1:-1;2008:4:69;1829:188;;;;:::o;1902:47:59:-;;;;;;;;;;;;;;;:::o;371:83:65:-;437:12;;371:83;;:::o;8909:729:59:-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;9022:20:59;;;;;;;;:7;:20;;;;;:27;9007:42;;;;8999:120;;;;;-1:-1:-1;;;;;8999:120:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9137:20;;;;9197:1;9137:20;;;:7;:20;;;;;:34;;9197:1;;9137:20;;:34;;;;;;;;;;;;;;;;;;:48;:34;;;;;:48;;-1:-1:-1;;;;;9137:48:59;:62;;9129:123;;;;;-1:-1:-1;;;;;9129:123:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9376:84;;;;9406:20;;;;:7;:20;;;;;:34;;9376:84;;;;9406:34;;;;;;;;;;;;;;;;;;;:48;:34;;;;;;:48;;9376:84;;;-1:-1:-1;;;;;9406:48:59;;;9376:84;;9456:3;9376:84;;;;;;;;;;;;;;;;;;9507:20;;;;;;;:7;:20;;;;;9528:27;;-1:-1:-1;;9528:31:59;;;9507:53;;;;;;;;;;;;;;;;9470:7;:20;9478:11;9470:20;;;;;;;;;;;;;;;9491:12;9470:34;;;;;;;;;;;;;;;;;;;;:90;;:34;;;;;;:90;;;;;;;;;;;;;;-1:-1:-1;;;;;;9470:90:59;-1:-1:-1;;;;;9470:90:59;;;;;;;;;;9600:20;;;;;:7;:20;;;;;;:27;;-1:-1:-1;;9600:31:59;;9570:61;;9600:31;9570:61;:::i;:::-;;8909:729;;:::o;20378:126::-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;20433:18:59;:25;;-1:-1:-1;;20433:25:59;;;;;20473:24;;;20493:3;20473:24;;;;;;;;;;;;;20378:126::o;13116:236::-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;13200:17:59;;;13192:54;;;;;-1:-1:-1;;;;;13192:54:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;13283:11;;13261:48;;;;;;;;;;;;;;;;;;;;;;;;13319:11;:26;13116:236::o;1665:38::-;;;;;;;;;:::o;18189:388::-;18271:12;18295:39;18315:5;18322:3;18327:6;18295:19;:39::i;:::-;18352:34;18367:5;18374:3;18379:6;18352:14;:34::i;:::-;18344:68;;;;;;;-1:-1:-1;;;;;18344:68:59;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;18344:68:59;;;;;;;;;;;;;;;18422:31;18447:5;18422:24;:31::i;:::-;18463:29;18488:3;18463:24;:29::i;:::-;18510:38;18529:5;18536:3;18541:6;18510:18;:38::i;:::-;18502:47;;;;;;;;-1:-1:-1;18566:4:59;18189:388;;;;;:::o;1145:31::-;;;-1:-1:-1;;;;;1145:31:59;;:::o;281:29:5:-;;;-1:-1:-1;;;;;281:29:5;;:::o;365:21:66:-;;;;;;:::o;15602:148:59:-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;15666:6:59;;-1:-1:-1;15666:6:59;;;;15658:15;;;;;;;;15683:6;:14;;-1:-1:-1;;15683:14:59;;;;;15712:31;;;-1:-1:-1;;;15731:6:59;;;15683:14;15731:6;15712:31;;;;15739:3;15712:31;;;;;;;;;;;;;;;;15602:148::o;1042:54::-;;;:::o;622:26:19:-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;622:26:19;;-1:-1:-1;622:26:19;:::o;20865:704:59:-;21002:12;350:1:19;20942:4:59;21002:12;;3717:165;3739:20;;;;;;;;:7;:20;;;;;:27;3735:31;;;;3717:165;;;3802:12;:69;;;-1:-1:-1;3819:20:59;;;;;;;;:7;:20;;;;;:23;;3860:10;;3819:23;;;;;;;;;;;;;;;;;:37;:23;;;;;:37;;-1:-1:-1;;;;;3819:37:59;:51;3802:69;3787:84;-1:-1:-1;3768:3:59;;3717:165;;;3895:9;:26;;;;;3909:12;3908:13;3895:26;3891:389;;;3941:22;;;350:1:19;3941:22:59;3937:243;;;3989:20;;;;;;;:7;:20;;;;;:27;:32;:55;;;;-1:-1:-1;4039:5:59;;-1:-1:-1;;;;;4039:5:59;4025:10;:19;3989:55;3981:113;;;;;;;-1:-1:-1;;;;;3981:113:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3937:243;;;4151:5;;-1:-1:-1;;;;;4151:5:59;4137:10;:19;4129:51;;;;;-1:-1:-1;;;;;4129:51:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;3891:389;;;4219:12;4211:58;;;;;;;-1:-1:-1;;;;;4211:58:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20965:7;4374:11;;4364:7;:21;;;;;;;;:26;4356:90;;;;;-1:-1:-1;;;;;4356:90:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4731:5;;-1:-1:-1;;;;;4731:5:59;4717:10;:19;4713:206;;;4761:21;;;;4760:22;4752:65;;;;;-1:-1:-1;;;;;4752:65:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;4713:206;;;4857:18;;;;;;;4856:19;4848:60;;;;;-1:-1:-1;;;;;4848:60:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21034:23:59;;;;21026:69;;;;;-1:-1:-1;;;;;21026:69:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21105:51;21133:1;21137:9;21148:7;21105:19;:51::i;:::-;21174:46;21197:1;21201:9;21212:7;21174:14;:46::i;:::-;21166:80;;;;;;;-1:-1:-1;;;;;21166:80:59;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;21166:80:59;;;;;;;;;;;;;;;21256:35;21281:9;21256:24;:35::i;:::-;21301:30;:28;:30::i;:::-;21356:12;;:25;;21373:7;21356:25;:16;:25;:::i;:::-;21341:12;:40;-1:-1:-1;;;;;21413:19:59;;:8;:19;;;;;;;;;;;:32;;21437:7;21413:23;:32::i;:::-;-1:-1:-1;;;;;21391:19:59;;:8;:19;;;;;;;;;;;;:54;;;;21460:26;;;;;;;21391:19;;21460:26;;;;;;;;;21501:40;;;;;;;;21518:1;-1:-1:-1;;;;;;;21501:40:59;;;21518:1;;21501:40;21518:1;;-1:-1:-1;;21518:1:59;-1:-1:-1;;;;;21501:40:59;;;;;;;;-1:-1:-1;21558:4:59;;20865:704;-1:-1:-1;;;;;;;20865:704:59:o;23749:993::-;23796:6;4374:11;;4364:7;:21;;;;;;;;:26;4356:90;;;;;-1:-1:-1;;;;;4356:90:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23821:51;23841:10;23861:1;23865:6;23821:19;:51::i;:::-;23890:11;;-1:-1:-1;;;;;23890:11:59;:25;;23882:82;;;;;-1:-1:-1;;;;;23882:82:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23982:46;23997:10;24017:1;24021:6;23982:14;:46::i;:::-;23974:80;;;;;;;-1:-1:-1;;;;;23974:80:59;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;23974:80:59;;;;;;;;;;;;;;;24091:10;24082:8;:20;;;;;;;;;;;24072:30;;;24064:100;;;;;-1:-1:-1;;;;;24064:100:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24174:36;24199:10;24174:24;:36::i;:::-;24220:30;:28;:30::i;:::-;24472:10;24463:8;:20;;;;;;;;;;;:32;;24488:6;24463:32;:24;:32;:::i;:::-;24449:10;24440:8;:20;;;;;;;;;;;:55;;;;24513:11;;:36;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24513:11:59;;;;:16;;:36;;;;;;;;;;;;;:11;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;24513:36:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;24513:36:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24513:36:59;24505:86;;;;;;;-1:-1:-1;;;;;24505:86:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24616:12;;:24;;24633:6;24616:24;:16;:24;:::i;:::-;24601:12;:39;24655:25;;;;;;;;24661:10;;24655:25;;;;;;;;;;24695:40;;;;;;;;24724:1;;24704:10;;-1:-1:-1;;;;;;;;;;;24695:40:59;;;;;;;;23749:993;;:::o;9907:373::-;10017:20;;;9985:7;10017:20;;;:7;:20;;;;;:27;9985:7;;10017:31;-1:-1:-1;10013:260:59;;;10089:20;;;;;;;:7;:20;;;;;:34;;10110:12;;10089:34;;;;;;;;;;;;;;;;;;;;;:39;10146:20;;;;;:7;:20;;;;;;;:34;;10167:12;;10146:34;;;;;;;;;;;;;;:48;:34;;;;;:48;;10064:144;;-1:-1:-1;;;;;;10146:48:59;;-1:-1:-1;10064:144:59;;10013:260;-1:-1:-1;10259:1:59;;-1:-1:-1;10259:1:59;10013:260;9907:373;;;;;:::o;22025:355::-;22128:12;;350:1:19;22113:4:59;22128:12;;3717:165;3739:20;;;;;;;;:7;:20;;;;;:27;3735:31;;;;3717:165;;;3802:12;:69;;;-1:-1:-1;3819:20:59;;;;;;;;:7;:20;;;;;:23;;3860:10;;3819:23;;;;;;;;;;;;;;;;;:37;:23;;;;;:37;;-1:-1:-1;;;;;3819:37:59;:51;3802:69;3787:84;-1:-1:-1;3768:3:59;;3717:165;;;3895:9;:26;;;;;3909:12;3908:13;3895:26;3891:389;;;3941:22;;;350:1:19;3941:22:59;3937:243;;;3989:20;;;;;;;:7;:20;;;;;:27;:32;:55;;;;-1:-1:-1;4039:5:59;;-1:-1:-1;;;;;4039:5:59;4025:10;:19;3989:55;3981:113;;;;;;;-1:-1:-1;;;;;3981:113:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3937:243;;;4151:5;;-1:-1:-1;;;;;4151:5:59;4137:10;:19;4129:51;;;;;-1:-1:-1;;;;;4129:51:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;3891:389;;;4219:12;4211:58;;;;;;;-1:-1:-1;;;;;4211:58:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22181:15;;22160:17;;:36;22152:86;;;;;-1:-1:-1;;;;;22152:86:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22265:1;22253:13;;22248:105;22272:10;:17;22268:1;:21;22248:105;;;22310:32;22315:10;22326:1;22315:13;;;;;;;;;;;;;;;;;;22330:8;22339:1;22330:11;;;;;;;;;;;;;;;;;;22310:4;:32::i;:::-;-1:-1:-1;22291:3:59;;;;;22248:105;;;-1:-1:-1;22369:4:59;;22025:355;-1:-1:-1;;;;;;;22025:355:59:o;27639:194::-;-1:-1:-1;;;;;27759:29:59;;27722:7;27759:29;;;:18;:29;;;;;27748:78;;27790:13;27805:20;27759:29;27805:9;:20::i;:::-;27748:10;:78::i;:::-;27741:85;27639:194;-1:-1:-1;;;27639:194:59:o;471:34:19:-;;;;:::o;403:26::-;;;;:::o;1857:38:59:-;1893:2;1857:38;:::o;11751:936::-;719:5:64;;12015:25:59;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;11870:16:59;;;;;11862:55;;;;;-1:-1:-1;;;;;11862:55:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;11950:20;;;;;;;;:7;:20;;;;;:27;11935:42;;;;11927:78;;;;;-1:-1:-1;;;;;11927:78:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;12050:9;;12086:20;;;;12050:9;12086:20;;;:7;:20;;;;;:34;;-1:-1:-1;;;;;12050:9:59;;;;12043:27;;12079:4;;12086:20;:34;;;;;;;;;;;;;;;;;;;;;;;;;;:48;;;12043:92;;;;;;-1:-1:-1;;;12043:92:59;;;-1:-1:-1;;;;;12043:92:59;;;;;;;12086:48;;;;12043:92;;;;;;;;;;12086:34;;12043:92;;;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;12043:92:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12043:92:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12043:92:59;;-1:-1:-1;12149:27:59;;;12145:427;;;12207:9;;12235:20;;;;12207:9;12235:20;;;:7;:20;;;;;:34;;-1:-1:-1;;;;;12207:9:59;;;;12200:34;;12235;;;;;;;;;;;;;;;;;:48;:34;;;;;:48;;-1:-1:-1;;;;;12235:48:59;12285:30;:17;12307:7;12285:21;:30::i;:::-;12200:116;;;;;;-1:-1:-1;;;12200:116:59;;;-1:-1:-1;;;;;12200:116:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12200:116:59;;;;5:2:-1;;;;30:1;27;20:12;5:2;12200:116:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12200:116:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12200:116:59;12192:169;;;;;;;-1:-1:-1;;;;;12192:169:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12145:427;;;12407:9;;12435:20;;;;12407:9;12435:20;;;:7;:20;;;;;:34;;-1:-1:-1;;;;;12407:9:59;;;;12400:34;;12435;;;;;;;;;;;;;;;;;:48;:34;;;;;:48;;-1:-1:-1;;;;;12435:48:59;12485:30;:7;12497:17;12485:11;:30::i;:::-;12400:116;;;;;;-1:-1:-1;;;12400:116:59;;;-1:-1:-1;;;;;12400:116:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12400:116:59;;;;5:2:-1;;;;30:1;27;20:12;5:2;12400:116:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12400:116:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12400:116:59;12392:169;;;;;;;-1:-1:-1;;;;;12392:169:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12586:94;;;;12622:20;;;;:7;:20;;;;;:34;;12586:94;;;;12622:34;;;;;;;;;;;;;;;;;;;:48;:34;;;;;;:48;;12586:94;;;-1:-1:-1;;;;;12622:48:59;;;12586:94;;;;;;;;;;;;;;;;;;;11751:936;;;;:::o;1223:26::-;;;-1:-1:-1;1223:26:59;;;;;:::o;318:33:19:-;350:1;318:33;:::o;3701:425:69:-;3842:10;3804:4;3834:19;;;:7;:19;;;;;;;;-1:-1:-1;;;;;3834:29:69;;;;;;;;;;3873:27;;;3869:164;;;3918:10;3942:1;3910:19;;;:7;:19;;;;;;;;-1:-1:-1;;;;;3910:29:69;;;;;;;;;:33;3869:164;;;3996:30;:8;4009:16;3996:30;:12;:30;:::i;:::-;3972:10;3964:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;3964:29:69;;;;;;;;;:62;3869:164;4052:10;4074:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;4043:61:69;;4074:29;;;;;;;;;;;4043:61;;;;;;;;;4052:10;4043:61;;;;;;;;;;;-1:-1:-1;4117:4:69;;3701:425;-1:-1:-1;;;3701:425:69:o;316:24:5:-;;;-1:-1:-1;;;;;316:24:5;;:::o;1131:99:65:-;-1:-1:-1;;;;;1209:16:65;1187:7;1209:16;;;;;;;;;;;;1131:99::o;827:111:64:-;719:5;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;903:5;;884:25;;-1:-1:-1;;;;;903:5:64;;;;884:25;;903:5;;884:25;915:5;:18;;-1:-1:-1;;;;;;915:18:64;;;827:111::o;1804:46:59:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;1804:46:59;;-1:-1:-1;1804:46:59;:::o;12797:186::-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;12882:53:59;;;;;;12904:12;12882:53;;;-1:-1:-1;;12882:53:59;;;;;;;;;;;;;;;;;;;12904:12;;12918:16;;12882:53;;;;;;;;;;12904:12;;12882:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12882:53:59;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;12882:53:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12945:31;;;;:12;;:31;;;;;:::i;:::-;;12797:186;:::o;167:31:5:-;;;;;;-1:-1:-1;;;;;167:31:5;;:::o;1570:41:59:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1570:41:59;:::o;22864:463::-;260:1:19;22960:4:59;22980:30;;;:7;:30;;;:37;22960:4;;22980:42;22976:85;;;23045:5;23038:12;;;;22976:85;-1:-1:-1;23086:1:59;23071:250;260:1:19;23093:30:59;;:7;:30;;;:37;:30;23089:41;;;23071:250;;;260:1:19;23174:30:59;;:7;:30;;;:33;;:30;:33;;;;;;;;;;;;;;;;;;;;;;;;;:47;;;23155:110;;;;;;-1:-1:-1;;;;;23155:110:59;;;;;;;;;;;;;;;;;;;;;;23174:47;;;;;23155:83;;:110;;;;;23174:33;;23155:110;;;;;;;;;23174:47;23155:110;;;5:2:-1;;;;30:1;27;20:12;5:2;23155:110:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;23155:110:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23155:110:59;23151:160;;;23292:4;23285:11;;;;23151:160;23132:3;;23071:250;;;22864:463;;;;;;:::o;238:20:64:-;;;-1:-1:-1;;;;;238:20:64;;:::o;267:45:19:-;311:1;267:45;:::o;341:20:66:-;;;;;;;;;;;;;;;-1:-1:-1;;341:20:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25725:162:59;25791:7;25817:63;25828:21;25851:13;25866;:11;:13::i;25817:63::-;25810:70;25725:162;-1:-1:-1;;25725:162:59:o;18861:1214::-;18972:4;19015:15;19257:14;19293:12;19327:17;19371:7;19448:29;18954:7;4374:11;;4364:7;:21;;;;;;;;:26;4356:90;;;;;-1:-1:-1;;;;;4356:90:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18993:6;;-1:-1:-1;18993:6:59;;;;18992:7;18988:1061;;;19033:5;19015:23;;19056:17;:35;19074:16;19081:8;;19074:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19074:6:59;;-1:-1:-1;;;;;19074:16:59:i;:::-;19056:35;;;;;;;;;;;;;-1:-1:-1;19056:35:59;;;;19052:89;;;19122:4;19109:17;;19052:89;311:1:19;19158:28:59;;:7;:28;;;:35;:40;19154:90;;;19225:4;19218:11;;;;19154:90;19274:5;19257:22;;19308:5;19293:20;;19347:5;19327:25;;19381:1;19371:11;;19366:603;311:1:19;19388:28:59;;:7;:28;;;:35;:28;19384:39;;;19366:603;;;311:1:19;19497:28:59;;:7;:28;;;:31;;:28;:31;;;;;;;;;;;;;;;;;;;:45;;;;;;;;;;-1:-1:-1;;;;;19497:45:59;-1:-1:-1;;;;;19480:78:59;;19559:5;19566:3;19571:7;19580:10;19480:111;;;;;-1:-1:-1;;;19480:111:59;;;;;;;-1:-1:-1;;;;;19480:111:59;-1:-1:-1;;;;;19480:111:59;;;;;;-1:-1:-1;;;;;19480:111:59;-1:-1:-1;;;;;19480:111:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19480:111:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;19480:111:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19480:111:59;;-1:-1:-1;19622:31:59;19613:5;:40;;;;;;;;;19609:103;;;19689:4;19677:16;;19609:103;19742:29;19733:5;:38;;;;;;;;;19729:99;;;19805:4;19795:14;;19729:99;19858:35;19849:5;:44;;;;;;;;;19845:110;;;19932:4;19917:19;;19845:110;19425:3;;;;;19366:603;;;19989:12;:51;;20012:9;:27;;20032:7;20012:27;;;20024:5;20012:27;19989:51;;;20004:4;19989:51;19982:58;;;;18988:1061;20063:5;20056:12;;4456:1;18861:1214;;;;;;;;;;;;:::o;1618:41::-;;;;;;:::o;10567:578::-;10679:20;;;10647:7;10679:20;;;:7;:20;;;;;:27;10647:7;;;;10679:31;-1:-1:-1;10675:464:59;;;-1:-1:-1;10743:1:59;10726:312;10750:20;;;;;;;:7;:20;;;;;:27;10746:31;;10726:312;;;10806:20;;;:37;:20;;;:7;:20;;;;;:23;;10838:5;;10806:20;10827:1;;10806:23;;;;;;;;;;;;;;;;;;;:28;:37;10802:222;;;10896:20;;;;;;;:7;:20;;;;;:23;;10917:1;;10896:23;;;;;;;;;;;;;;;;;;;;;:28;10948:20;;;;;:7;:20;;;;;;;:23;;10969:1;;10948:23;;;;;;;;;;;;;;:37;:23;;;;;:37;;10865:140;;-1:-1:-1;;;;;;10948:37:59;;-1:-1:-1;10865:140:59;;10802:222;10779:3;;10726:312;;;11071:1;;-1:-1:-1;11071:1:59;;-1:-1:-1;10675:464:59;10567:578;;;;;;:::o;20160:135::-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;20218:21:59;:28;;-1:-1:-1;;20218:28:59;20242:4;20218:28;;;20261:27;;;20284:3;20261:27;;;;;;;;;;;;;20160:135::o;214:47:19:-;260:1;214:47;:::o;17586:373:59:-;17649:12;17673:44;17693:10;17705:3;17710:6;17673:19;:44::i;:::-;17735:39;17750:10;17762:3;17767:6;17735:14;:39::i;:::-;17727:73;;;;;;;-1:-1:-1;;;;;17727:73:59;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;17727:73:59;;;;;;;;;;;;;;;17810:36;17835:10;17810:24;:36::i;:::-;17856:29;17881:3;17856:24;:29::i;:::-;17903:27;17918:3;17923:6;17903:14;:27::i;:::-;17895:36;;;;;;;;-1:-1:-1;17948:4:59;17586:373;;;;:::o;23497:120::-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;23570:11:59;:40;;-1:-1:-1;;;;;;23570:40:59;-1:-1:-1;;;;;23570:40:59;;;;;;;;;;23497:120::o;204:29:5:-;;;-1:-1:-1;;;;;204:29:5;;:::o;357:40:19:-;396:1;357:40;:::o;14603:429:59:-;719:5:64;;14691:9:59;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;-1:-1:-1;14703:6:59;14686:340;14715:49;14727:18;:6;14738;14727:18;:10;:18;:::i;:::-;14747:9;:16;14715:11;:49::i;:::-;14711:1;:53;14686:340;;;14794:9;:16;14790:20;;14789:56;;;;;14816:23;14826:9;14836:1;14826:12;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14826:12:59;14816:9;:23::i;:::-;:28;14789:56;14785:231;;;14896:5;14865:14;:28;14880:9;14890:1;14880:12;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14880:12:59;14865:28;;;;;;;;;;;;:36;;-1:-1:-1;;14865:36:59;;;;;;;;;;14934:9;14944:16;;-1:-1:-1;;14944:20:59;;;14934:31;;;;;;;;;;;;;;;;14919:9;:12;;-1:-1:-1;;;;;14934:31:59;;;;14929:1;;14919:12;;;;;;;;;;;;;;;:46;;-1:-1:-1;;;;;;14919:46:59;-1:-1:-1;;;;;14919:46:59;;;;;;;;;;14983:9;:18;;;;;-1:-1:-1;;14983:18:59;;;:::i;:::-;;14785:231;14766:3;;14686:340;;239:36:5;;;-1:-1:-1;;;;;239:36:5;;:::o;303:26:17:-;;;;;;;;;;;;;;;-1:-1:-1;;303:26:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2946:293:69;3106:10;3044:4;3098:19;;;:7;:19;;;;;;;;-1:-1:-1;;;;;3098:29:69;;;;;;;;;;:46;;3132:11;3098:33;:46::i;:::-;3066:10;3058:19;;;;:7;:19;;;;;;;;-1:-1:-1;;;;;3058:29:69;;;;;;;;;;;;:87;;;3156:61;;;;;;3058:29;;3156:61;;;;;;;;;;;-1:-1:-1;3230:4:69;2946:293;;;;:::o;558:28:19:-;;;;:::o;2336:153:69:-;-1:-1:-1;;;;;2459:15:69;;;2435:7;2459:15;;;-1:-1:-1;2459:15:69;;;;;;;;:25;;;;;;;;;;;;;2336:153::o;15230:99:59:-;15306:9;:16;15230:99;:::o;1100:103:64:-;719:5;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;1169:29;1188:9;1169:18;:29::i;:::-;1100:103;:::o;503:418:5:-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;594:16:5;;577:63;;;-1:-1:-1;;;;;577:63:5;;;;;;;;;;;;;;;;;;;;;594:16;;;;-1:-1:-1;;;;;594:16:5;;-1:-1:-1;;577:63:5;;;;;;;;;;;;;-1:-1:-1;594:16:5;577:63;;;5:2:-1;;;;30:1;27;20:12;5:2;577:63:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;577:63:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;577:63:5;560:14;:80;;-1:-1:-1;;;;;;560:80:5;-1:-1:-1;;;;;560:80:5;;;;;;691:16;;674:70;;;-1:-1:-1;;;;;674:70:5;;577:63;674:70;;;;;;;;;;;;;;;;;;560:80;691:16;;;;;;;-1:-1:-1;;674:70:5;;;;;577:63;674:70;;;;;-1:-1:-1;691:16:5;674:70;;;5:2:-1;;;;30:1;27;20:12;5:2;674:70:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;674:70:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;674:70:5;650:21;:94;;-1:-1:-1;;;;;;650:94:5;-1:-1:-1;;;;;650:94:5;;;;;;788:16;;771:63;;;-1:-1:-1;;;;;771:63:5;;674:70;771:63;;;;;;;;;;;;;;;;;;;;650:94;788:16;;;;;;;-1:-1:-1;;771:63:5;;;;;674:70;;771:63;;;;;-1:-1:-1;788:16:5;771:63;;;5:2:-1;;;;30:1;27;20:12;5:2;771:63:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;771:63:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;771:63:5;754:14;:80;;-1:-1:-1;;;;;;754:80:5;-1:-1:-1;;;;;754:80:5;;;;;;873:16;;856:58;;;-1:-1:-1;;;;;856:58:5;;771:63;856:58;;;;;;;;;;;;;;;;;;754:80;873:16;;;;;;;-1:-1:-1;;856:58:5;;;;;771:63;856:58;;;;;-1:-1:-1;873:16:5;856:58;;;5:2:-1;;;;30:1;27;20:12;5:2;856:58:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;856:58:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;856:58:5;844:9;:70;;-1:-1:-1;;;;;;844:70:5;-1:-1:-1;;;;;844:70:5;;;;;;;;;503:418::o;6491:230:59:-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;782:14:61;;;;781:15;773:24;;;;;;803:14;:21;;-1:-1:-1;;803:21:61;820:4;803:21;;;6662:52:59;;;;;;;;;;;;;;;;;;;;;;;;6673:14;;6662:52;6689:5;;;;;;6662:52;;6689:5;;;;6662:52;;;;;;;;;;;6696:8;6706:7;6662:10;:52::i;:::-;-1:-1:-1;;837:14:61;:22;;-1:-1:-1;;837:22:61;;;-1:-1:-1;;;6491:230:59:o;11404:148::-;719:5:64;;-1:-1:-1;;;;;719:5:64;705:10;:19;697:28;;;;;;11484:9:59;;11504:5;;11478:41;;;;;;-1:-1:-1;;;;;11504:5:59;;;11478:41;;;;;;;;;;;;11484:9;;;;;11478:25;;:41;;;;;;;;;;;;;;-1:-1:-1;11484:9:59;11478:41;;;5:2:-1;;;;30:1;27;20:12;5:2;11478:41:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;11478:41:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11478:41:59;11470:75;;;;;;;-1:-1:-1;;;;;11470:75:59;;;;;;;;;;;;;;;;;;;;;;;;;;;1505:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1505:59:59;-1:-1:-1;1505:59:59;:::o;25272:295::-;25348:7;396:1:19;25334:4:59;25348:7;;3717:165;3739:20;;;;;;;;:7;:20;;;;;:27;3735:31;;;;3717:165;;;3802:12;:69;;;-1:-1:-1;3819:20:59;;;;;;;;:7;:20;;;;;:23;;3860:10;;3819:23;;;;;;;;;;;;;;;;;:37;:23;;;;;:37;;-1:-1:-1;;;;;3819:37:59;:51;3802:69;3787:84;-1:-1:-1;3768:3:59;;3717:165;;;3895:9;:26;;;;;3909:12;3908:13;3895:26;3891:389;;;3941:22;;;350:1:19;3941:22:59;3937:243;;;3989:20;;;;;;;:7;:20;;;;;:27;:32;:55;;;;-1:-1:-1;4039:5:59;;-1:-1:-1;;;;;4039:5:59;4025:10;:19;3989:55;3981:113;;;;;;;-1:-1:-1;;;;;3981:113:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3937:243;;;4151:5;;-1:-1:-1;;;;;4151:5:59;4137:10;:19;4129:51;;;;;-1:-1:-1;;;;;4129:51:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;3891:389;;;4219:12;4211:58;;;;;;;-1:-1:-1;;;;;4211:58:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25375:19;;-1:-1:-1;;;25367:41:59;;;;;;25440:19;;;25462:1;25440:23;25418:45;;;;25478:46;;;25520:3;25478:46;;;;;;;;;;;;;25541:19;;25534:26;;25272:295;;;;;:::o;13553:685::-;13650:11;;;13649:31;;-1:-1:-1;;;;;;13667:12:59;;;;;;;13649:31;13645:68;;;13696:7;;13645:68;13783:14;13793:3;13783:9;:14::i;:::-;:19;13782:44;;;;-1:-1:-1;;;;;;13808:17:59;;;;13782:44;13778:111;;;13858:13;;:20;;13876:1;13858:20;:17;:20;:::i;:::-;13842:13;:36;13778:111;13974:16;13984:5;13974:9;:16::i;:::-;13964:6;:26;13960:93;;;14022:13;;:20;;14040:1;14022:20;:17;:20;:::i;:::-;14006:13;:36;13960:93;-1:-1:-1;;;;;14103:19:59;;;;;;:14;:19;;;;;;;;14102:20;:43;;;;-1:-1:-1;;;;;;14127:17:59;;;;14102:43;14098:133;;;-1:-1:-1;14161:9:59;27:10:-1;;39:1;23:18;;;45:23;;;14161:19:59;;;;-1:-1:-1;;;;;;14161:19:59;-1:-1:-1;;;;;14161:19:59;;;;;;;;;-1:-1:-1;14194:19:59;;;:14;14161:19;14194;;;;;:26;;-1:-1:-1;;14194:26:59;;;;;;-1:-1:-1;13553:685:59:o;16136:149::-;-1:-1:-1;;;;;16226:29:59;;;;;;:18;:29;;;;;16208:70;;16257:20;16226:29;16257:9;:20::i;:::-;16208:17;:70::i;736:470:69:-;842:4;-1:-1:-1;;;;;864:17:69;;;;856:26;;;;;;-1:-1:-1;;;;;906:15:69;;:8;:15;;;;;;;;;;;896:25;;;888:34;;;;;;-1:-1:-1;;;;;946:14:69;;;;;;-1:-1:-1;946:14:69;;;;;;;;961:10;946:26;;;;;;;;936:36;;;928:45;;;;;;-1:-1:-1;;;;;998:15:69;;:8;:15;;;;;;;;;;;:27;;1018:6;998:19;:27::i;:::-;-1:-1:-1;;;;;980:15:69;;;:8;:15;;;;;;;;;;;:45;;;;1047:13;;;;;;;:25;;1065:6;1047:17;:25::i;:::-;-1:-1:-1;;;;;1031:13:69;;;:8;:13;;;;;;;;;;;:41;;;;1107:14;;;;;-1:-1:-1;1107:14:69;;;;;1122:10;1107:26;;;;;;;:38;;1138:6;1107:30;:38::i;:::-;-1:-1:-1;;;;;1078:14:69;;;;;;;-1:-1:-1;1078:14:69;;;;;;;;1093:10;1078:26;;;;;;;:67;;;;1156:28;;;;;;;-1:-1:-1;;1156:28:69;;;;1078:14;;;;1156:28;;;1078:14;-1:-1:-1;1078:14:69;-1:-1:-1;;;;;1156:28:69;;;;;;;;;;-1:-1:-1;1197:4:69;736:470;;;;;:::o;15852:121:59:-;15911:55;15929:21;15952:13;:11;:13::i;15911:55::-;15852:121::o;1214:123:63:-;1293:5;;;1311:6;;;;1304:14;;;1042:110;1100:7;1122:6;;;;1115:14;;;;-1:-1:-1;1142:5:63;;;1042:110::o;26149:1298:59:-;26271:7;26971:11;26996;27074;26315:19;;26298:13;:36;;26290:45;;;;;;;;26440:18;;26436:55;;;26479:1;26472:8;;;;26436:55;26504:18;;:23;26500:74;;;26550:13;26543:20;;;;26500:74;26618:13;26587:11;26599:1;26587:14;;;;;;;;;;;;;;;;;;;;;;;:27;:44;26583:102;;26654:11;26666:1;26654:14;;;;;;;;;;;;;;;;;;;;:20;;;26647:27;;;;26583:102;26710:18;;26749:13;;26710:18;;-1:-1:-1;;26710:22:59;;;26698:35;;;;;;;;;;;;;;;;:48;;;:64;26694:115;;;26785:13;26778:20;;;;26694:115;26834:18;;26874:13;;26834:18;;-1:-1:-1;;26834:22:59;;;26822:35;;;;;;;;;;;;;;;;:48;;;:65;26818:144;;;26922:18;;;;-1:-1:-1;;26922:22:59;;;26910:35;;;;;26818:144;27010:18;;26985:1;;-1:-1:-1;;;27010:22:59;;-1:-1:-1;27042:360:59;27055:3;27049;:9;27042:360;;;27102:1;27089:9;;;27088:15;27074:29;;27154:13;27121:11;27133:3;27121:16;;;;;;;;;;;;;;;;;;;;:29;;;:46;27117:117;;;27193:3;27187:9;;27214:5;;27117:117;27283:13;27251:11;27263:3;27251:16;;;;;;;;;;;;;;;;;;;;:29;;;:45;27247:145;;;27322:3;27328:1;27322:7;27316:13;;27247:145;;;27374:3;27368:9;;27247:145;27042:360;;;27418:11;27430:3;27418:16;;;;;;;;;;;;;;;;;;;;:22;;;27411:29;;26149:1298;;;;;;;;;:::o;24871:261::-;24923:10;24945:8;25006:6;24971:1;24956:5;:12;:16;:35;;24990:1;24956:35;;;24975:5;:12;24956:35;24945:46;;25015:1;25006:10;;25001:125;25022:3;25018:1;:7;25001:125;;;25110:1;25106;25100:3;:7;:11;25095:1;:17;25089:1;:24;25076:5;25082:1;25076:8;;;;;;;;;;;;;;;-1:-1:-1;25076:8:59;;;;;;25071:14;:43;-1:-1:-1;;;25059:9:59;;;;:55;25052:63;;;;25027:3;;25001:125;;;24871:261;;;;;:::o;608:321:65:-;671:4;-1:-1:-1;;;;;691:17:65;;;;683:26;;;;;;742:10;733:8;:20;;;;;;;;;;;723:30;;;715:39;;;;;;793:10;784:8;:20;;;;;;;;;;;:32;;809:6;784:32;:24;:32;:::i;:::-;770:10;761:8;:20;;;;;;;;;;;:55;;;;-1:-1:-1;;;;;838:13:65;;;;;;:25;;856:6;838:17;:25::i;:::-;-1:-1:-1;;;;;822:13:65;;:8;:13;;;;;;;;;;;:41;;;;874:33;;;;;;;-1:-1:-1;;822:13:65;;883:10;;874:33;;822:8;:13;-1:-1:-1;822:8:65;-1:-1:-1;;;;;874:33:65;;;;;;;;;-1:-1:-1;920:4:65;608:321;;;;:::o;409:101:62:-;470:7;496:1;492;:5;:13;;504:1;492:13;;;-1:-1:-1;500:1:62;;409:101;-1:-1:-1;409:101:62:o;1338:171:64:-;-1:-1:-1;;;;;1408:23:64;;;;1400:32;;;;;;1464:5;;1443:38;;-1:-1:-1;;;;;1443:38:64;;;;1464:5;;1443:38;;1464:5;;1443:38;1487:5;:17;;-1:-1:-1;;;;;;1487:17:64;-1:-1:-1;;;;;1487:17:64;;;;;;;;;;1338:171::o;7405:1273:59:-;7602:14;;7586:57;;;;;;-1:-1:-1;;;;;7586:57:59;;;;;;;;;-1:-1:-1;;;;;;;;;;7602:14:59;;;;;7586:41;;:57;;;;;-1:-1:-1;;7586:57:59;;;;;;;;-1:-1:-1;7602:14:59;7586:57;;;5:2:-1;;;;30:1;27;20:12;5:2;7586:57:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7586:57:59;;;;7699:14;7653:61;;7743:13;-1:-1:-1;;;;;7743:21:59;;:23;;;;;-1:-1:-1;;;7743:23:59;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7743:23:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7743:23:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7743:23:59;7784:40;:19;;;;;;:7;7743:23;7784:19;;;;:26;7743:23;;-1:-1:-1;1893:2:59;-1:-1:-1;7776:84:59;;;;;-1:-1:-1;;;;;7776:84:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;7891:13;-1:-1:-1;;;;;7891:23:59;;:25;;;;;-1:-1:-1;;;7891:25:59;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7891:25:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7891:25:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7891:25:59;;-1:-1:-1;7934:22:59;;;;7926:81;;;;;-1:-1:-1;;;;;7926:81:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8064:9;;8058:52;;;;;;-1:-1:-1;;;;;8058:52:59;;;;;;;;;;;;;;;8064:9;;;;;8058:24;;:52;;;;;;;;;;;;;;-1:-1:-1;8064:9:59;8058:52;;;5:2:-1;;;;30:1;27;20:12;5:2;8058:52:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8058:52:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8058:52:59;8050:100;;;;;;;-1:-1:-1;;;;;8050:100:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8227:27;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8227:20:59;;;;;:27;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;8227:27:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8227:27:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8227:27:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8227:27:59;8311:9;;8305:41;;;;;;-1:-1:-1;;;;;8305:41:59;;;;;;;;;;;;;;;8227:27;;-1:-1:-1;8311:9:59;;;8305:24;;:41;;;;;8227:27;;8305:41;;;;;;;;-1:-1:-1;8311:9:59;8305:41;;;5:2:-1;;;;30:1;27;20:12;5:2;8305:41:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8305:41:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8305:41:59;8297:84;;;;;;;-1:-1:-1;;;;;8297:84:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;8454:13;-1:-1:-1;;;;;8454:21:59;;:23;;;;;-1:-1:-1;;;8454:23:59;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8454:23:59;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8454:23:59;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8454:23:59;8487:19;;;;;;;:7;8454:23;8487:19;;;;;;;8512:30;;;;;;;;;;-1:-1:-1;;;;;8512:30:59;;;;;;;;;27:10:-1;;-1:-1;23:18;;;45:23;;8487:56:59;;;;;;;;;-1:-1:-1;8487:56:59;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;8487:56:59;;;;;;;;;;;8583:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8667:3;-1:-1:-1;8583:88:59;;;;;8454:23;;-1:-1:-1;8487:19:59;;8583:88;;;;;;;;;;7405:1273;;;;;;;;;:::o;16492:907::-;16629:19;;:24;16625:61;;;16669:7;;16625:61;16778:19;;:24;16774:247;;;16853:123;;;;;;;;;16900:19;;16853:123;;;;;;;;;27:10:-1;;39:1;23:18;;;45:23;;-1:-1;16818:172:59;;;;;;;;;;;;;;;;;;;;;;;17004:7;;16774:247;17135:19;;17094;;;;-1:-1:-1;;17094:23:59;;;17081:37;;;;;;;;;;;;;;;;:50;;;:73;17077:110;;;17170:7;;17077:110;17271:111;;;;;;;;;17314:19;;17271:111;;;;;;;;;27:10:-1;;39:1;23:18;;;45:23;;-1:-1;17240:152:59;;;;;;;;;;;;;;;;;;;;;;;;16492:907::o;928:26908::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;928:26908:59;;;-1:-1:-1;928:26908:59;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;928:26908:59;;;-1:-1:-1;928:26908:59;;;;;;;;;;;;;;;;;;;;", + "source": "pragma solidity ^0.4.24;\n\nimport \"openzeppelin-solidity/contracts/math/Math.sol\";\nimport \"../interfaces/IERC20.sol\";\nimport \"../interfaces/ISecurityToken.sol\";\nimport \"../interfaces/IModule.sol\";\nimport \"../interfaces/IModuleFactory.sol\";\nimport \"../interfaces/IModuleRegistry.sol\";\nimport \"../interfaces/IST20.sol\";\nimport \"../modules/TransferManager/ITransferManager.sol\";\nimport \"../modules/PermissionManager/IPermissionManager.sol\";\nimport \"../interfaces/ITokenBurner.sol\";\nimport \"../RegistryUpdater.sol\";\nimport \"openzeppelin-solidity/contracts/ReentrancyGuard.sol\";\n\n/**\n* @title Security Token contract\n* @notice SecurityToken is an ERC20 token with added capabilities:\n* @notice - Implements the ST-20 Interface\n* @notice - Transfers are restricted\n* @notice - Modules can be attached to it to control its behaviour\n* @notice - ST should not be deployed directly, but rather the SecurityTokenRegistry should be used\n*/\ncontract SecurityToken is ISecurityToken, ReentrancyGuard, RegistryUpdater {\n using SafeMath for uint256;\n\n bytes32 public constant securityTokenVersion = \"0.0.1\";\n\n // Reference to token burner contract\n ITokenBurner public tokenBurner;\n\n // Use to halt all the transactions\n bool public freeze = false;\n\n struct ModuleData {\n bytes32 name;\n address moduleAddress;\n }\n\n // Structures to maintain checkpoints of balances for governance / dividends\n struct Checkpoint {\n uint256 checkpointId;\n uint256 value;\n }\n\n mapping (address => Checkpoint[]) public checkpointBalances;\n Checkpoint[] public checkpointTotalSupply;\n\n bool public finishedIssuerMinting = false;\n bool public finishedSTOMinting = false;\n\n mapping (bytes4 => bool) transferFunctions;\n\n // Module list should be order agnostic!\n mapping (uint8 => ModuleData[]) public modules;\n\n uint8 public constant MAX_MODULES = 20;\n\n mapping (address => bool) public investorListed;\n\n // Emit at the time when module get added\n event LogModuleAdded(\n uint8 indexed _type,\n bytes32 _name,\n address _moduleFactory,\n address _module,\n uint256 _moduleCost,\n uint256 _budget,\n uint256 _timestamp\n );\n\n // Emit when the token details get updated\n event LogUpdateTokenDetails(string _oldDetails, string _newDetails);\n // Emit when the granularity get changed\n event LogGranularityChanged(uint256 _oldGranularity, uint256 _newGranularity);\n // Emit when Module get removed from the securityToken\n event LogModuleRemoved(uint8 indexed _type, address _module, uint256 _timestamp);\n // Emit when the budget allocated to a module is changed\n event LogModuleBudgetChanged(uint8 indexed _moduleType, address _module, uint256 _budget);\n // Emit when all the transfers get freeze\n event LogFreezeTransfers(bool _freeze, uint256 _timestamp);\n // Emit when new checkpoint created\n event LogCheckpointCreated(uint256 indexed _checkpointId, uint256 _timestamp);\n // Emit when the minting get finished for the Issuer\n event LogFinishMintingIssuer(uint256 _timestamp);\n // Emit when the minting get finished for the STOs\n event LogFinishMintingSTO(uint256 _timestamp);\n // Change the STR address in the event of a upgrade\n event LogChangeSTRAddress(address indexed _oldAddress, address indexed _newAddress);\n\n // 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\n // for other _moduleType we allow both issuer and module.\n modifier onlyModule(uint8 _moduleType, bool _fallback) {\n //Loop over all modules of type _moduleType\n bool isModuleType = false;\n for (uint8 i = 0; i < modules[_moduleType].length; i++) {\n isModuleType = isModuleType || (modules[_moduleType][i].moduleAddress == msg.sender);\n }\n if (_fallback && !isModuleType) {\n if (_moduleType == STO_KEY)\n require(modules[_moduleType].length == 0 && msg.sender == owner, \"Sender is not owner or STO module is attached\");\n else\n require(msg.sender == owner, \"Sender is not owner\");\n } else {\n require(isModuleType, \"Sender is not correct module type\");\n }\n _;\n }\n\n modifier checkGranularity(uint256 _amount) {\n require(_amount % granularity == 0, \"Unable to modify token balances at this granularity\");\n _;\n }\n\n // Checks whether the minting is allowed or not, check for the owner if owner is no the msg.sender then check\n // for the finishedSTOMinting flag because only STOs and owner are allowed for minting\n modifier isMintingAllowed() {\n if (msg.sender == owner) {\n require(!finishedIssuerMinting, \"Minting is finished for Issuer\");\n } else {\n require(!finishedSTOMinting, \"Minting is finished for STOs\");\n }\n _;\n }\n\n /**\n * @notice Constructor\n * @param _name Name of the SecurityToken\n * @param _symbol Symbol of the Token\n * @param _decimals Decimals for the securityToken\n * @param _granularity granular level of the token\n * @param _tokenDetails Details of the token that are stored off-chain (IPFS hash)\n * @param _polymathRegistry Contract address of the polymath registry\n */\n constructor (\n string _name,\n string _symbol,\n uint8 _decimals,\n uint256 _granularity,\n string _tokenDetails,\n address _polymathRegistry\n )\n public\n DetailedERC20(_name, _symbol, _decimals)\n RegistryUpdater(_polymathRegistry)\n {\n //When it is created, the owner is the STR\n updateFromRegistry();\n tokenDetails = _tokenDetails;\n granularity = _granularity;\n transferFunctions[bytes4(keccak256(\"transfer(address,uint256)\"))] = true;\n transferFunctions[bytes4(keccak256(\"transferFrom(address,address,uint256)\"))] = true;\n transferFunctions[bytes4(keccak256(\"mint(address,uint256)\"))] = true;\n transferFunctions[bytes4(keccak256(\"burn(uint256)\"))] = true;\n }\n\n /**\n * @notice Function used to attach the module in security token\n * @param _moduleFactory Contract address of the module factory that needs to be attached\n * @param _data Data used for the intialization of the module factory variables\n * @param _maxCost Maximum cost of the Module factory\n * @param _budget Budget of the Module factory\n */\n function addModule(\n address _moduleFactory,\n bytes _data,\n uint256 _maxCost,\n uint256 _budget\n ) external onlyOwner nonReentrant {\n _addModule(_moduleFactory, _data, _maxCost, _budget);\n }\n\n /**\n * @notice _addModule handles the attachment (or replacement) of modules for the ST\n * @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it\n * @dev to control restrictions on transfers.\n * @dev You are allowed to add a new moduleType if:\n * @dev - there is no existing module of that type yet added\n * @dev - the last member of the module list is replacable\n * @param _moduleFactory is the address of the module factory to be added\n * @param _data is data packed into bytes used to further configure the module (See STO usage)\n * @param _maxCost max amount of POLY willing to pay to module. (WIP)\n */\n function _addModule(address _moduleFactory, bytes _data, uint256 _maxCost, uint256 _budget) internal {\n //Check that module exists in registry - will throw otherwise\n IModuleRegistry(moduleRegistry).useModule(_moduleFactory);\n IModuleFactory moduleFactory = IModuleFactory(_moduleFactory);\n uint8 moduleType = moduleFactory.getType();\n require(modules[moduleType].length < MAX_MODULES, \"Limit of MAX MODULES is reached\");\n uint256 moduleCost = moduleFactory.setupCost();\n require(moduleCost <= _maxCost, \"Max Cost is always be greater than module cost\");\n //Approve fee for module\n require(ERC20(polyToken).approve(_moduleFactory, moduleCost), \"Not able to approve the module cost\");\n //Creates instance of module from factory\n address module = moduleFactory.deploy(_data);\n //Approve ongoing budget\n require(ERC20(polyToken).approve(module, _budget), \"Not able to approve the budget\");\n //Add to SecurityToken module map\n bytes32 moduleName = moduleFactory.getName();\n modules[moduleType].push(ModuleData(moduleName, module));\n //Emit log event\n emit LogModuleAdded(moduleType, moduleName, _moduleFactory, module, moduleCost, _budget, now);\n }\n\n /**\n * @notice Removes a module attached to the SecurityToken\n * @param _moduleType is which type of module we are trying to remove\n * @param _moduleIndex is the index of the module within the chosen type\n */\n function removeModule(uint8 _moduleType, uint8 _moduleIndex) external onlyOwner {\n require(_moduleIndex < modules[_moduleType].length,\n \"Module index doesn't exist as per the choosen module type\");\n require(modules[_moduleType][_moduleIndex].moduleAddress != address(0),\n \"Module contract address should not be 0x\");\n //Take the last member of the list, and replace _moduleIndex with this, then shorten the list by one\n emit LogModuleRemoved(_moduleType, modules[_moduleType][_moduleIndex].moduleAddress, now);\n modules[_moduleType][_moduleIndex] = modules[_moduleType][modules[_moduleType].length - 1];\n modules[_moduleType].length = modules[_moduleType].length - 1;\n }\n\n /**\n * @notice Returns module list for a module type\n * @param _moduleType is which type of module we are trying to get\n * @param _moduleIndex is the index of the module within the chosen type\n * @return bytes32\n * @return address\n */\n function getModule(uint8 _moduleType, uint _moduleIndex) public view returns (bytes32, address) {\n if (modules[_moduleType].length > 0) {\n return (\n modules[_moduleType][_moduleIndex].name,\n modules[_moduleType][_moduleIndex].moduleAddress\n );\n } else {\n return (\"\", address(0));\n }\n\n }\n\n /**\n * @notice returns module list for a module name - will return first match\n * @param _moduleType is which type of module we are trying to get\n * @param _name is the name of the module within the chosen type\n * @return bytes32\n * @return address\n */\n function getModuleByName(uint8 _moduleType, bytes32 _name) public view returns (bytes32, address) {\n if (modules[_moduleType].length > 0) {\n for (uint256 i = 0; i < modules[_moduleType].length; i++) {\n if (modules[_moduleType][i].name == _name) {\n return (\n modules[_moduleType][i].name,\n modules[_moduleType][i].moduleAddress\n );\n }\n }\n return (\"\", address(0));\n } else {\n return (\"\", address(0));\n }\n }\n\n /**\n * @notice allows the owner to withdraw unspent POLY stored by them on the ST.\n * @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee.\n * @param _amount amount of POLY to withdraw\n */\n function withdrawPoly(uint256 _amount) public onlyOwner {\n require(ERC20(polyToken).transfer(owner, _amount), \"In-sufficient balance\");\n }\n\n /**\n * @notice allows owner to approve more POLY to one of the modules\n * @param _moduleType module type\n * @param _moduleIndex module index\n * @param _budget new budget\n */\n function changeModuleBudget(uint8 _moduleType, uint8 _moduleIndex, uint256 _budget) public onlyOwner {\n require(_moduleType != 0, \"Module type cannot be zero\");\n require(_moduleIndex < modules[_moduleType].length, \"Incorrrect module index\");\n uint256 _currentAllowance = IERC20(polyToken).allowance(address(this), modules[_moduleType][_moduleIndex].moduleAddress);\n if (_budget < _currentAllowance) {\n require(IERC20(polyToken).decreaseApproval(modules[_moduleType][_moduleIndex].moduleAddress, _currentAllowance.sub(_budget)), \"Insufficient balance to decreaseApproval\");\n } else {\n require(IERC20(polyToken).increaseApproval(modules[_moduleType][_moduleIndex].moduleAddress, _budget.sub(_currentAllowance)), \"Insufficient balance to increaseApproval\");\n }\n emit LogModuleBudgetChanged(_moduleType, modules[_moduleType][_moduleIndex].moduleAddress, _budget);\n }\n\n /**\n * @notice change the tokenDetails\n * @param _newTokenDetails New token details\n */\n function updateTokenDetails(string _newTokenDetails) public onlyOwner {\n emit LogUpdateTokenDetails(tokenDetails, _newTokenDetails);\n tokenDetails = _newTokenDetails;\n }\n\n /**\n * @notice allows owner to change token granularity\n * @param _granularity granularity level of the token\n */\n function changeGranularity(uint256 _granularity) public onlyOwner {\n require(_granularity != 0, \"Granularity can not be 0\");\n emit LogGranularityChanged(granularity, _granularity);\n granularity = _granularity;\n }\n\n /**\n * @notice keeps track of the number of non-zero token holders\n * @param _from sender of transfer\n * @param _to receiver of transfer\n * @param _value value of transfer\n */\n function adjustInvestorCount(address _from, address _to, uint256 _value) internal {\n if ((_value == 0) || (_from == _to)) {\n return;\n }\n // Check whether receiver is a new token holder\n if ((balanceOf(_to) == 0) && (_to != address(0))) {\n investorCount = investorCount.add(1);\n }\n // Check whether sender is moving all of their tokens\n if (_value == balanceOf(_from)) {\n investorCount = investorCount.sub(1);\n }\n //Also adjust investor list\n if (!investorListed[_to] && (_to != address(0))) {\n investors.push(_to);\n investorListed[_to] = true;\n }\n\n }\n\n /**\n * @notice removes addresses with zero balances from the investors list\n * @param _start Index in investor list at which to start removing zero balances\n * @param _iters Max number of iterations of the for loop\n * NB - pruning this list will mean you may not be able to iterate over investors on-chain as of a historical checkpoint\n */\n function pruneInvestors(uint256 _start, uint256 _iters) public onlyOwner {\n for (uint256 i = _start; i < Math.min256(_start.add(_iters), investors.length); i++) {\n if ((i < investors.length) && (balanceOf(investors[i]) == 0)) {\n investorListed[investors[i]] = false;\n investors[i] = investors[investors.length - 1];\n investors.length--;\n }\n }\n }\n\n /**\n * @notice gets length of investors array\n * NB - this length may differ from investorCount if list has not been pruned of zero balance investors\n * @return length\n */\n function getInvestorsLength() public view returns(uint256) {\n return investors.length;\n }\n\n /**\n * @notice freeze all the transfers\n */\n function freezeTransfers() public onlyOwner {\n require(!freeze);\n freeze = true;\n emit LogFreezeTransfers(freeze, now);\n }\n\n /**\n * @notice un-freeze all the transfers\n */\n function unfreezeTransfers() public onlyOwner {\n require(freeze);\n freeze = false;\n emit LogFreezeTransfers(freeze, now);\n }\n\n /**\n * @notice adjust totalsupply at checkpoint after minting or burning tokens\n */\n function adjustTotalSupplyCheckpoints() internal {\n adjustCheckpoints(checkpointTotalSupply, totalSupply());\n }\n\n /**\n * @notice adjust token holder balance at checkpoint after a token transfer\n * @param _investor address of the token holder affected\n */\n function adjustBalanceCheckpoints(address _investor) internal {\n adjustCheckpoints(checkpointBalances[_investor], balanceOf(_investor));\n }\n\n /**\n * @notice store the changes to the checkpoint objects\n * @param _checkpoints the affected checkpoint object array\n * @param _newValue the new value that needs to be stored\n */\n function adjustCheckpoints(Checkpoint[] storage _checkpoints, uint256 _newValue) internal {\n //No checkpoints set yet\n if (currentCheckpointId == 0) {\n return;\n }\n //No previous checkpoint data - add current balance against checkpoint\n if (_checkpoints.length == 0) {\n _checkpoints.push(\n Checkpoint({\n checkpointId: currentCheckpointId,\n value: _newValue\n })\n );\n return;\n }\n //No new checkpoints since last update\n if (_checkpoints[_checkpoints.length - 1].checkpointId == currentCheckpointId) {\n return;\n }\n //New checkpoint, so record balance\n _checkpoints.push(\n Checkpoint({\n checkpointId: currentCheckpointId,\n value: _newValue\n })\n );\n }\n\n /**\n * @notice Overloaded version of the transfer function\n * @param _to receiver of transfer\n * @param _value value of transfer\n * @return bool success\n */\n function transfer(address _to, uint256 _value) public returns (bool success) {\n adjustInvestorCount(msg.sender, _to, _value);\n require(verifyTransfer(msg.sender, _to, _value), \"Transfer is not valid\");\n adjustBalanceCheckpoints(msg.sender);\n adjustBalanceCheckpoints(_to);\n require(super.transfer(_to, _value));\n return true;\n }\n\n /**\n * @notice Overloaded version of the transferFrom function\n * @param _from sender of transfer\n * @param _to receiver of transfer\n * @param _value value of transfer\n * @return bool success\n */\n function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {\n adjustInvestorCount(_from, _to, _value);\n require(verifyTransfer(_from, _to, _value), \"Transfer is not valid\");\n adjustBalanceCheckpoints(_from);\n adjustBalanceCheckpoints(_to);\n require(super.transferFrom(_from, _to, _value));\n return true;\n }\n\n /**\n * @notice validate transfer with TransferManager module if it exists\n * @dev TransferManager module has a key of 2\n * @param _from sender of transfer\n * @param _to receiver of transfer\n * @param _amount value of transfer\n * @return bool\n */\n function verifyTransfer(address _from, address _to, uint256 _amount) public checkGranularity(_amount) returns (bool) {\n if (!freeze) {\n bool isTransfer = false;\n if (transferFunctions[getSig(msg.data)]) {\n isTransfer = true;\n }\n if (modules[TRANSFERMANAGER_KEY].length == 0) {\n return true;\n }\n bool isInvalid = false;\n bool isValid = false;\n bool isForceValid = false;\n for (uint8 i = 0; i < modules[TRANSFERMANAGER_KEY].length; i++) {\n ITransferManager.Result valid = ITransferManager(modules[TRANSFERMANAGER_KEY][i].moduleAddress).verifyTransfer(_from, _to, _amount, isTransfer);\n if (valid == ITransferManager.Result.INVALID) {\n isInvalid = true;\n }\n if (valid == ITransferManager.Result.VALID) {\n isValid = true;\n }\n if (valid == ITransferManager.Result.FORCE_VALID) {\n isForceValid = true;\n }\n }\n return isForceValid ? true : (isInvalid ? false : isValid);\n }\n return false;\n }\n\n /**\n * @notice End token minting period permanently for Issuer\n */\n function finishMintingIssuer() public onlyOwner {\n finishedIssuerMinting = true;\n emit LogFinishMintingIssuer(now);\n }\n\n /**\n * @notice End token minting period permanently for STOs\n */\n function finishMintingSTO() public onlyOwner {\n finishedSTOMinting = true;\n emit LogFinishMintingSTO(now);\n }\n\n /**\n * @notice mints new tokens and assigns them to the target _investor.\n * @dev Can only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet)\n * @param _investor Address to whom the minted tokens will be dilivered\n * @param _amount Number of tokens get minted\n * @return success\n */\n function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) checkGranularity(_amount) isMintingAllowed() returns (bool success) {\n require(_investor != address(0), \"Investor address should not be 0x\");\n adjustInvestorCount(address(0), _investor, _amount);\n require(verifyTransfer(address(0), _investor, _amount), \"Transfer is not valid\");\n adjustBalanceCheckpoints(_investor);\n adjustTotalSupplyCheckpoints();\n totalSupply_ = totalSupply_.add(_amount);\n balances[_investor] = balances[_investor].add(_amount);\n emit Minted(_investor, _amount);\n emit Transfer(address(0), _investor, _amount);\n return true;\n }\n\n /**\n * @notice mints new tokens and assigns them to the target _investor.\n * Can only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet)\n * @param _investors A list of addresses to whom the minted tokens will be dilivered\n * @param _amounts A list of number of tokens get minted and transfer to corresponding address of the investor from _investor[] list\n * @return success\n */\n function mintMulti(address[] _investors, uint256[] _amounts) public onlyModule(STO_KEY, true) returns (bool success) {\n require(_investors.length == _amounts.length, \"Mis-match in the length of the arrays\");\n for (uint256 i = 0; i < _investors.length; i++) {\n mint(_investors[i], _amounts[i]);\n }\n return true;\n }\n\n /**\n * @notice Validate permissions with PermissionManager if it exists, If no Permission return false\n * @dev Note that IModule withPerm will allow ST owner all permissions anyway\n * @dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions)\n * @param _delegate address of delegate\n * @param _module address of PermissionManager module\n * @param _perm the permissions\n * @return success\n */\n function checkPermission(address _delegate, address _module, bytes32 _perm) public view returns(bool) {\n if (modules[PERMISSIONMANAGER_KEY].length == 0) {\n return false;\n }\n\n for (uint8 i = 0; i < modules[PERMISSIONMANAGER_KEY].length; i++) {\n if (IPermissionManager(modules[PERMISSIONMANAGER_KEY][i].moduleAddress).checkPermission(_delegate, _module, _perm)) {\n return true;\n }\n }\n }\n\n /**\n * @notice used to set the token Burner address. It only be called by the owner\n * @param _tokenBurner Address of the token burner contract\n */\n function setTokenBurner(address _tokenBurner) public onlyOwner {\n tokenBurner = ITokenBurner(_tokenBurner);\n }\n\n /**\n * @notice Burn function used to burn the securityToken\n * @param _value No. of token that get burned\n */\n function burn(uint256 _value) checkGranularity(_value) public {\n adjustInvestorCount(msg.sender, address(0), _value);\n require(tokenBurner != address(0), \"Token Burner contract address is not set yet\");\n require(verifyTransfer(msg.sender, address(0), _value), \"Transfer is not valid\");\n require(_value <= balances[msg.sender], \"Value should no be greater than the balance of msg.sender\");\n adjustBalanceCheckpoints(msg.sender);\n adjustTotalSupplyCheckpoints();\n // no need to require value <= totalSupply, since that would imply the\n // sender's balance is greater than the totalSupply, which *should* be an assertion failure\n\n balances[msg.sender] = balances[msg.sender].sub(_value);\n require(tokenBurner.burn(msg.sender, _value), \"Token burner process is not validated\");\n totalSupply_ = totalSupply_.sub(_value);\n emit Burnt(msg.sender, _value);\n emit Transfer(msg.sender, address(0), _value);\n }\n\n /**\n * @notice Get function signature from _data\n * @param _data passed data\n * @return bytes4 sig\n */\n function getSig(bytes _data) internal pure returns (bytes4 sig) {\n uint len = _data.length < 4 ? _data.length : 4;\n for (uint i = 0; i < len; i++) {\n sig = bytes4(uint(sig) + uint(_data[i]) * (2 ** (8 * (len - 1 - i))));\n }\n }\n\n /**\n * @notice Creates a checkpoint that can be used to query historical balances / totalSuppy\n * @return uint256\n */\n function createCheckpoint() public onlyModule(CHECKPOINT_KEY, true) returns(uint256) {\n require(currentCheckpointId < 2**256 - 1);\n currentCheckpointId = currentCheckpointId + 1;\n emit LogCheckpointCreated(currentCheckpointId, now);\n return currentCheckpointId;\n }\n\n /**\n * @notice Queries totalSupply as of a defined checkpoint\n * @param _checkpointId Checkpoint ID to query\n * @return uint256\n */\n function totalSupplyAt(uint256 _checkpointId) public view returns(uint256) {\n return getValueAt(checkpointTotalSupply, _checkpointId, totalSupply());\n }\n\n /**\n * @notice Queries value at a defined checkpoint\n * @param checkpoints is array of Checkpoint objects\n * @param _checkpointId Checkpoint ID to query\n * @param _currentValue Current value of checkpoint\n * @return uint256\n */\n function getValueAt(Checkpoint[] storage checkpoints, uint256 _checkpointId, uint256 _currentValue) internal view returns(uint256) {\n require(_checkpointId <= currentCheckpointId);\n //Checkpoint id 0 is when the token is first created - everyone has a zero balance\n if (_checkpointId == 0) {\n return 0;\n }\n if (checkpoints.length == 0) {\n return _currentValue;\n }\n if (checkpoints[0].checkpointId >= _checkpointId) {\n return checkpoints[0].value;\n }\n if (checkpoints[checkpoints.length - 1].checkpointId < _checkpointId) {\n return _currentValue;\n }\n if (checkpoints[checkpoints.length - 1].checkpointId == _checkpointId) {\n return checkpoints[checkpoints.length - 1].value;\n }\n uint256 min = 0;\n uint256 max = checkpoints.length - 1;\n while (max > min) {\n uint256 mid = (max + min) / 2;\n if (checkpoints[mid].checkpointId == _checkpointId) {\n max = mid;\n break;\n }\n if (checkpoints[mid].checkpointId < _checkpointId) {\n min = mid + 1;\n } else {\n max = mid;\n }\n }\n return checkpoints[max].value;\n }\n\n /**\n * @notice Queries balances as of a defined checkpoint\n * @param _investor Investor to query balance for\n * @param _checkpointId Checkpoint ID to query as of\n */\n function balanceOfAt(address _investor, uint256 _checkpointId) public view returns(uint256) {\n return getValueAt(checkpointBalances[_investor], _checkpointId, balanceOf(_investor));\n }\n\n}\n", + "sourcePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/tokens/SecurityToken.sol", + "ast": { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/tokens/SecurityToken.sol", + "exportedSymbols": { + "SecurityToken": [ + 22534 + ] + }, + "id": 22535, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 20614, + "literals": [ + "solidity", + "^", + "0.4", + ".24" + ], + "nodeType": "PragmaDirective", + "src": "0:24:59" + }, + { + "absolutePath": "openzeppelin-solidity/contracts/math/Math.sol", + "file": "openzeppelin-solidity/contracts/math/Math.sol", + "id": 20615, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 22662, + "src": "26:55:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IERC20.sol", + "file": "../interfaces/IERC20.sol", + "id": 20616, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9493, + "src": "82:34:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/ISecurityToken.sol", + "file": "../interfaces/ISecurityToken.sol", + "id": 20617, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 10098, + "src": "117:42:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IModule.sol", + "file": "../interfaces/IModule.sol", + "id": 20618, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9656, + "src": "160:35:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IModuleFactory.sol", + "file": "../interfaces/IModuleFactory.sol", + "id": 20619, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9893, + "src": "196:42:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IModuleRegistry.sol", + "file": "../interfaces/IModuleRegistry.sol", + "id": 20620, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9916, + "src": "239:43:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IST20.sol", + "file": "../interfaces/IST20.sol", + "id": 20621, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9987, + "src": "283:33:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/TransferManager/ITransferManager.sol", + "file": "../modules/TransferManager/ITransferManager.sol", + "id": 20622, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 18521, + "src": "317:57:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/PermissionManager/IPermissionManager.sol", + "file": "../modules/PermissionManager/IPermissionManager.sol", + "id": 20623, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 13248, + "src": "375:61:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/ITokenBurner.sol", + "file": "../interfaces/ITokenBurner.sol", + "id": 20624, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 10219, + "src": "437:40:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/RegistryUpdater.sol", + "file": "../RegistryUpdater.sol", + "id": 20625, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 677, + "src": "478:32:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "openzeppelin-solidity/contracts/ReentrancyGuard.sol", + "file": "openzeppelin-solidity/contracts/ReentrancyGuard.sol", + "id": 20626, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 22591, + "src": "511:61:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "baseContracts": [ + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 20627, + "name": "ISecurityToken", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 10097, + "src": "954:14:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ISecurityToken_$10097", + "typeString": "contract ISecurityToken" + } + }, + "id": 20628, + "nodeType": "InheritanceSpecifier", + "src": "954:14:59" + }, + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 20629, + "name": "ReentrancyGuard", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 22590, + "src": "970:15:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ReentrancyGuard_$22590", + "typeString": "contract ReentrancyGuard" + } + }, + "id": 20630, + "nodeType": "InheritanceSpecifier", + "src": "970:15:59" + }, + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 20631, + "name": "RegistryUpdater", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 676, + "src": "987:15:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RegistryUpdater_$676", + "typeString": "contract RegistryUpdater" + } + }, + "id": 20632, + "nodeType": "InheritanceSpecifier", + "src": "987:15:59" + } + ], + "contractDependencies": [ + 676, + 9986, + 10097, + 22590, + 22841, + 22937, + 22971, + 23014, + 23046, + 23293 + ], + "contractKind": "contract", + "documentation": "@title Security Token contract\n@notice SecurityToken is an ERC20 token with added capabilities:\n@notice - Implements the ST-20 Interface\n@notice - Transfers are restricted\n@notice - Modules can be attached to it to control its behaviour\n@notice - ST should not be deployed directly, but rather the SecurityTokenRegistry should be used", + "fullyImplemented": true, + "id": 22534, + "linearizedBaseContracts": [ + 22534, + 676, + 22590, + 10097, + 22841, + 9986, + 22971, + 23293, + 22937, + 23014, + 23046 + ], + "name": "SecurityToken", + "nodeType": "ContractDefinition", + "nodes": [ + { + "id": 20635, + "libraryName": { + "contractScope": null, + "id": 20633, + "name": "SafeMath", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 22755, + "src": "1015:8:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SafeMath_$22755", + "typeString": "library SafeMath" + } + }, + "nodeType": "UsingForDirective", + "src": "1009:27:59", + "typeName": { + "id": 20634, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1028:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "constant": true, + "id": 20638, + "name": "securityTokenVersion", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1042:54:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 20636, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1042:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "302e302e31", + "id": 20637, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1089:7:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_ae209a0b48f21c054280f2455d32cf309387644879d9acbd8ffc199163811885", + "typeString": "literal_string \"0.0.1\"" + }, + "value": "0.0.1" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20640, + "name": "tokenBurner", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1145:31:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + }, + "typeName": { + "contractScope": null, + "id": 20639, + "name": "ITokenBurner", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 10218, + "src": "1145:12:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 20643, + "name": "freeze", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1223:26:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20641, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1223:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20642, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1244:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "canonicalName": "SecurityToken.ModuleData", + "id": 20648, + "members": [ + { + "constant": false, + "id": 20645, + "name": "name", + "nodeType": "VariableDeclaration", + "scope": 20648, + "src": "1284:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 20644, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1284:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20647, + "name": "moduleAddress", + "nodeType": "VariableDeclaration", + "scope": 20648, + "src": "1306:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20646, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1306:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "ModuleData", + "nodeType": "StructDefinition", + "scope": 22534, + "src": "1256:78:59", + "visibility": "public" + }, + { + "canonicalName": "SecurityToken.Checkpoint", + "id": 20653, + "members": [ + { + "constant": false, + "id": 20650, + "name": "checkpointId", + "nodeType": "VariableDeclaration", + "scope": 20653, + "src": "1449:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20649, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1449:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20652, + "name": "value", + "nodeType": "VariableDeclaration", + "scope": 20653, + "src": "1479:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20651, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1479:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Checkpoint", + "nodeType": "StructDefinition", + "scope": 22534, + "src": "1421:78:59", + "visibility": "public" + }, + { + "constant": false, + "id": 20658, + "name": "checkpointBalances", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1505:59:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint[])" + }, + "typeName": { + "id": 20657, + "keyType": { + "id": 20654, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1514:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "1505:33:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint[])" + }, + "valueType": { + "baseType": { + "contractScope": null, + "id": 20655, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "1525:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 20656, + "length": null, + "nodeType": "ArrayTypeName", + "src": "1525:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 20661, + "name": "checkpointTotalSupply", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1570:41:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint[]" + }, + "typeName": { + "baseType": { + "contractScope": null, + "id": 20659, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "1570:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 20660, + "length": null, + "nodeType": "ArrayTypeName", + "src": "1570:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 20664, + "name": "finishedIssuerMinting", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1618:41:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20662, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1618:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20663, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1654:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20667, + "name": "finishedSTOMinting", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1665:38:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20665, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1665:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20666, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1698:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20671, + "name": "transferFunctions", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1710:42:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + }, + "typeName": { + "id": 20670, + "keyType": { + "id": 20668, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "1719:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "Mapping", + "src": "1710:24:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + }, + "valueType": { + "id": 20669, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1729:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20676, + "name": "modules", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1804:46:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData[])" + }, + "typeName": { + "id": 20675, + "keyType": { + "id": 20672, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "1813:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "Mapping", + "src": "1804:31:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData[])" + }, + "valueType": { + "baseType": { + "contractScope": null, + "id": 20673, + "name": "ModuleData", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20648, + "src": "1822:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage_ptr", + "typeString": "struct SecurityToken.ModuleData" + } + }, + "id": 20674, + "length": null, + "nodeType": "ArrayTypeName", + "src": "1822:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.ModuleData[]" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": true, + "id": 20679, + "name": "MAX_MODULES", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1857:38:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20677, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "1857:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "3230", + "id": 20678, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1893:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_20_by_1", + "typeString": "int_const 20" + }, + "value": "20" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20683, + "name": "investorListed", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1902:47:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + }, + "typeName": { + "id": 20682, + "keyType": { + "id": 20680, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1911:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "1902:25:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + }, + "valueType": { + "id": 20681, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1922:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "anonymous": false, + "documentation": null, + "id": 20699, + "name": "LogModuleAdded", + "nodeType": "EventDefinition", + "parameters": { + "id": 20698, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20685, + "indexed": true, + "name": "_type", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2032:19:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20684, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "2032:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20687, + "indexed": false, + "name": "_name", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2061:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 20686, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2061:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20689, + "indexed": false, + "name": "_moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2084:22:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20688, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2084:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20691, + "indexed": false, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2116:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20690, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2116:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20693, + "indexed": false, + "name": "_moduleCost", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2141:19:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20692, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2141:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20695, + "indexed": false, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2170:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20694, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2170:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20697, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2195:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20696, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2195:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2022:197:59" + }, + "src": "2002:218:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20705, + "name": "LogUpdateTokenDetails", + "nodeType": "EventDefinition", + "parameters": { + "id": 20704, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20701, + "indexed": false, + "name": "_oldDetails", + "nodeType": "VariableDeclaration", + "scope": 20705, + "src": "2301:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20700, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "2301:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20703, + "indexed": false, + "name": "_newDetails", + "nodeType": "VariableDeclaration", + "scope": 20705, + "src": "2321:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20702, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "2321:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2300:40:59" + }, + "src": "2273:68:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20711, + "name": "LogGranularityChanged", + "nodeType": "EventDefinition", + "parameters": { + "id": 20710, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20707, + "indexed": false, + "name": "_oldGranularity", + "nodeType": "VariableDeclaration", + "scope": 20711, + "src": "2419:23:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20706, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2419:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20709, + "indexed": false, + "name": "_newGranularity", + "nodeType": "VariableDeclaration", + "scope": 20711, + "src": "2444:23:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20708, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2444:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2418:50:59" + }, + "src": "2391:78:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20719, + "name": "LogModuleRemoved", + "nodeType": "EventDefinition", + "parameters": { + "id": 20718, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20713, + "indexed": true, + "name": "_type", + "nodeType": "VariableDeclaration", + "scope": 20719, + "src": "2556:19:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20712, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "2556:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20715, + "indexed": false, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 20719, + "src": "2577:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20714, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2577:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20717, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20719, + "src": "2594:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20716, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2594:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2555:58:59" + }, + "src": "2533:81:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20727, + "name": "LogModuleBudgetChanged", + "nodeType": "EventDefinition", + "parameters": { + "id": 20726, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20721, + "indexed": true, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 20727, + "src": "2709:25:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20720, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "2709:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20723, + "indexed": false, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 20727, + "src": "2736:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20722, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2736:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20725, + "indexed": false, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 20727, + "src": "2753:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20724, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2753:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2708:61:59" + }, + "src": "2680:90:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20733, + "name": "LogFreezeTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 20732, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20729, + "indexed": false, + "name": "_freeze", + "nodeType": "VariableDeclaration", + "scope": 20733, + "src": "2846:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20728, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2846:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20731, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20733, + "src": "2860:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20730, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2860:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2845:34:59" + }, + "src": "2821:59:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20739, + "name": "LogCheckpointCreated", + "nodeType": "EventDefinition", + "parameters": { + "id": 20738, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20735, + "indexed": true, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 20739, + "src": "2952:29:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20734, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2952:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20737, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20739, + "src": "2983:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20736, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2983:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2951:51:59" + }, + "src": "2925:78:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20743, + "name": "LogFinishMintingIssuer", + "nodeType": "EventDefinition", + "parameters": { + "id": 20742, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20741, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20743, + "src": "3094:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20740, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3094:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3093:20:59" + }, + "src": "3065:49:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20747, + "name": "LogFinishMintingSTO", + "nodeType": "EventDefinition", + "parameters": { + "id": 20746, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20745, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20747, + "src": "3200:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20744, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3200:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3199:20:59" + }, + "src": "3174:46:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20753, + "name": "LogChangeSTRAddress", + "nodeType": "EventDefinition", + "parameters": { + "id": 20752, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20749, + "indexed": true, + "name": "_oldAddress", + "nodeType": "VariableDeclaration", + "scope": 20753, + "src": "3307:27:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20748, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3307:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20751, + "indexed": true, + "name": "_newAddress", + "nodeType": "VariableDeclaration", + "scope": 20753, + "src": "3336:27:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20750, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3336:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3306:58:59" + }, + "src": "3281:84:59" + }, + { + "body": { + "id": 20833, + "nodeType": "Block", + "src": "3622:675:59", + "statements": [ + { + "assignments": [ + 20760 + ], + "declarations": [ + { + "constant": false, + "id": 20760, + "name": "isModuleType", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3682:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20759, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3682:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20762, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20761, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3702:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "3682:25:59" + }, + { + "body": { + "id": 20791, + "nodeType": "Block", + "src": "3773:109:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 20789, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 20776, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "3787:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 20788, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20777, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "3802:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20786, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20778, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "3819:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 20780, + "indexExpression": { + "argumentTypes": null, + "id": 20779, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3827:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3819:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 20782, + "indexExpression": { + "argumentTypes": null, + "id": 20781, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20764, + "src": "3840:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3819:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 20783, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "3819:37:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20784, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "3860:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20785, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3860:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3819:51:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 20787, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "3818:53:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3802:69:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3787:84:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20790, + "nodeType": "ExpressionStatement", + "src": "3787:84:59" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20772, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20767, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20764, + "src": "3735:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20768, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "3739:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 20770, + "indexExpression": { + "argumentTypes": null, + "id": 20769, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3747:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3739:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 20771, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3739:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3735:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20792, + "initializationExpression": { + "assignments": [ + 20764 + ], + "declarations": [ + { + "constant": false, + "id": 20764, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3722:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20763, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "3722:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20766, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 20765, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3732:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "3722:11:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 20774, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "3768:3:59", + "subExpression": { + "argumentTypes": null, + "id": 20773, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20764, + "src": "3768:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 20775, + "nodeType": "ExpressionStatement", + "src": "3768:3:59" + }, + "nodeType": "ForStatement", + "src": "3717:165:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 20796, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20793, + "name": "_fallback", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20757, + "src": "3895:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "id": 20795, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "3908:13:59", + "subExpression": { + "argumentTypes": null, + "id": 20794, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "3909:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3895:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 20830, + "nodeType": "Block", + "src": "4197:83:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20826, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "4219:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "53656e646572206973206e6f7420636f7272656374206d6f64756c652074797065", + "id": 20827, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4233:35:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_18ea84476249f5cf0264794bb4497de0f9386f65e85fd6aa7b9a26fda3f47826", + "typeString": "literal_string \"Sender is not correct module type\"" + }, + "value": "Sender is not correct module type" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_18ea84476249f5cf0264794bb4497de0f9386f65e85fd6aa7b9a26fda3f47826", + "typeString": "literal_string \"Sender is not correct module type\"" + } + ], + "id": 20825, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4211:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20828, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4211:58:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20829, + "nodeType": "ExpressionStatement", + "src": "4211:58:59" + } + ] + }, + "id": 20831, + "nodeType": "IfStatement", + "src": "3891:389:59", + "trueBody": { + "id": 20824, + "nodeType": "Block", + "src": "3923:268:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 20799, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20797, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3941:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20798, + "name": "STO_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10025, + "src": "3956:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "3941:22:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20819, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20816, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "4137:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20817, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "4137:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20818, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "4151:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4137:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "53656e646572206973206e6f74206f776e6572", + "id": 20820, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4158:21:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c31e61005312bc4f751533ef9aaa8e9a41448b72bb628fe51500ef66060b25c4", + "typeString": "literal_string \"Sender is not owner\"" + }, + "value": "Sender is not owner" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c31e61005312bc4f751533ef9aaa8e9a41448b72bb628fe51500ef66060b25c4", + "typeString": "literal_string \"Sender is not owner\"" + } + ], + "id": 20815, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4129:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20821, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4129:51:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20822, + "nodeType": "ExpressionStatement", + "src": "4129:51:59" + }, + "id": 20823, + "nodeType": "IfStatement", + "src": "3937:243:59", + "trueBody": { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 20811, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20806, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20801, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "3989:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 20803, + "indexExpression": { + "argumentTypes": null, + "id": 20802, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3997:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3989:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 20804, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3989:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 20805, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4020:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "3989:32:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20810, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20807, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "4025:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20808, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "4025:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20809, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "4039:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4025:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3989:55:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c65206973206174746163686564", + "id": 20812, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4046:47:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_27aa5ed9c12058eab3c15a7622391d8d8cf66ea7b8ce97824ef531556d7ebbe2", + "typeString": "literal_string \"Sender is not owner or STO module is attached\"" + }, + "value": "Sender is not owner or STO module is attached" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_27aa5ed9c12058eab3c15a7622391d8d8cf66ea7b8ce97824ef531556d7ebbe2", + "typeString": "literal_string \"Sender is not owner or STO module is attached\"" + } + ], + "id": 20800, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "3981:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20813, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3981:113:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20814, + "nodeType": "ExpressionStatement", + "src": "3981:113:59" + } + } + ] + } + }, + { + "id": 20832, + "nodeType": "PlaceholderStatement", + "src": "4289:1:59" + } + ] + }, + "documentation": null, + "id": 20834, + "name": "onlyModule", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 20758, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20755, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3587:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20754, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "3587:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20757, + "name": "_fallback", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3606:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20756, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3606:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3586:35:59" + }, + "src": "3567:730:59", + "visibility": "internal" + }, + { + "body": { + "id": 20848, + "nodeType": "Block", + "src": "4346:118:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20843, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20841, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20839, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20836, + "src": "4364:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "%", + "rightExpression": { + "argumentTypes": null, + "id": 20840, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "4374:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4364:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 20842, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4389:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4364:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732061742074686973206772616e756c6172697479", + "id": 20844, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4392:53:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_58b4cb5c3b872c2661ef43443d2a3bc9a81f03995da6b03c67ed8d670b6a9a2c", + "typeString": "literal_string \"Unable to modify token balances at this granularity\"" + }, + "value": "Unable to modify token balances at this granularity" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_58b4cb5c3b872c2661ef43443d2a3bc9a81f03995da6b03c67ed8d670b6a9a2c", + "typeString": "literal_string \"Unable to modify token balances at this granularity\"" + } + ], + "id": 20838, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4356:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20845, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4356:90:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20846, + "nodeType": "ExpressionStatement", + "src": "4356:90:59" + }, + { + "id": 20847, + "nodeType": "PlaceholderStatement", + "src": "4456:1:59" + } + ] + }, + "documentation": null, + "id": 20849, + "name": "checkGranularity", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 20837, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20836, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 20849, + "src": "4329:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20835, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4329:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4328:17:59" + }, + "src": "4303:161:59", + "visibility": "internal" + }, + { + "body": { + "id": 20871, + "nodeType": "Block", + "src": "4703:233:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20854, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20851, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "4717:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20852, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "4717:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20853, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "4731:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4717:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 20868, + "nodeType": "Block", + "src": "4834:85:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20864, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4856:19:59", + "subExpression": { + "argumentTypes": null, + "id": 20863, + "name": "finishedSTOMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20667, + "src": "4857:18:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d696e74696e672069732066696e697368656420666f722053544f73", + "id": 20865, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4877:30:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1b2eb8774382bd7c01e52ec9b26ebd3d636110a215a12592de5928013b58c623", + "typeString": "literal_string \"Minting is finished for STOs\"" + }, + "value": "Minting is finished for STOs" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_1b2eb8774382bd7c01e52ec9b26ebd3d636110a215a12592de5928013b58c623", + "typeString": "literal_string \"Minting is finished for STOs\"" + } + ], + "id": 20862, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4848:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20866, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4848:60:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20867, + "nodeType": "ExpressionStatement", + "src": "4848:60:59" + } + ] + }, + "id": 20869, + "nodeType": "IfStatement", + "src": "4713:206:59", + "trueBody": { + "id": 20861, + "nodeType": "Block", + "src": "4738:90:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20857, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4760:22:59", + "subExpression": { + "argumentTypes": null, + "id": 20856, + "name": "finishedIssuerMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20664, + "src": "4761:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d696e74696e672069732066696e697368656420666f7220497373756572", + "id": 20858, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4784:32:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c19de2e165bb1c8a94b3685a5659527ec56c0c30abe571d67de7f55d580e920e", + "typeString": "literal_string \"Minting is finished for Issuer\"" + }, + "value": "Minting is finished for Issuer" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c19de2e165bb1c8a94b3685a5659527ec56c0c30abe571d67de7f55d580e920e", + "typeString": "literal_string \"Minting is finished for Issuer\"" + } + ], + "id": 20855, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4752:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20859, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4752:65:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20860, + "nodeType": "ExpressionStatement", + "src": "4752:65:59" + } + ] + } + }, + { + "id": 20870, + "nodeType": "PlaceholderStatement", + "src": "4928:1:59" + } + ] + }, + "documentation": null, + "id": 20872, + "name": "isMintingAllowed", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 20850, + "nodeType": "ParameterList", + "parameters": [], + "src": "4700:2:59" + }, + "src": "4675:261:59", + "visibility": "internal" + }, + { + "body": { + "id": 20946, + "nodeType": "Block", + "src": "5628:486:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 20895, + "name": "updateFromRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 675, + "src": "5689:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 20896, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5689:20:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20897, + "nodeType": "ExpressionStatement", + "src": "5689:20:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20900, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 20898, + "name": "tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9948, + "src": "5719:12:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 20899, + "name": "_tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20882, + "src": "5734:13:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + "src": "5719:28:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "id": 20901, + "nodeType": "ExpressionStatement", + "src": "5719:28:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20904, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 20902, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "5757:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 20903, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20880, + "src": "5771:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5757:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 20905, + "nodeType": "ExpressionStatement", + "src": "5757:26:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20914, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20906, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "5793:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20912, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7472616e7366657228616464726573732c75696e7432353629", + "id": 20909, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5828:27:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b", + "typeString": "literal_string \"transfer(address,uint256)\"" + }, + "value": "transfer(address,uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b", + "typeString": "literal_string \"transfer(address,uint256)\"" + } + ], + "id": 20908, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "5818:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20910, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5818:38:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20907, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5811:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20911, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5811:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "5793:65:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20913, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5861:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5793:72:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20915, + "nodeType": "ExpressionStatement", + "src": "5793:72:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20924, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20916, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "5875:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20922, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7472616e7366657246726f6d28616464726573732c616464726573732c75696e7432353629", + "id": 20919, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5910:39:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_23b872dd7302113369cda2901243429419bec145408fa8b352b3dd92b66c680b", + "typeString": "literal_string \"transferFrom(address,address,uint256)\"" + }, + "value": "transferFrom(address,address,uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_23b872dd7302113369cda2901243429419bec145408fa8b352b3dd92b66c680b", + "typeString": "literal_string \"transferFrom(address,address,uint256)\"" + } + ], + "id": 20918, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "5900:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20920, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5900:50:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20917, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5893:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20921, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5893:58:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "5875:77:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20923, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5955:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5875:84:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20925, + "nodeType": "ExpressionStatement", + "src": "5875:84:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20934, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20926, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "5969:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20932, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "6d696e7428616464726573732c75696e7432353629", + "id": 20929, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6004:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f2842", + "typeString": "literal_string \"mint(address,uint256)\"" + }, + "value": "mint(address,uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f2842", + "typeString": "literal_string \"mint(address,uint256)\"" + } + ], + "id": 20928, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "5994:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20930, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5994:34:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20927, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5987:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20931, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5987:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "5969:61:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20933, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6033:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5969:68:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20935, + "nodeType": "ExpressionStatement", + "src": "5969:68:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20944, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20936, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "6047:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20942, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "6275726e2875696e7432353629", + "id": 20939, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6082:15:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_42966c689b5afe9b9b3f8a7103b2a19980d59629bfd6a20a60972312ed41d836", + "typeString": "literal_string \"burn(uint256)\"" + }, + "value": "burn(uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_42966c689b5afe9b9b3f8a7103b2a19980d59629bfd6a20a60972312ed41d836", + "typeString": "literal_string \"burn(uint256)\"" + } + ], + "id": 20938, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "6072:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20940, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6072:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20937, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "6065:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20941, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6065:34:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "6047:53:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20943, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6103:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "6047:60:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20945, + "nodeType": "ExpressionStatement", + "src": "6047:60:59" + } + ] + }, + "documentation": "@notice Constructor\n@param _name Name of the SecurityToken\n@param _symbol Symbol of the Token\n@param _decimals Decimals for the securityToken\n@param _granularity granular level of the token\n@param _tokenDetails Details of the token that are stored off-chain (IPFS hash)\n@param _polymathRegistry Contract address of the polymath registry", + "id": 20947, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 20887, + "name": "_name", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20874, + "src": "5558:5:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 20888, + "name": "_symbol", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20876, + "src": "5565:7:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 20889, + "name": "_decimals", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20878, + "src": "5574:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 20890, + "modifierName": { + "argumentTypes": null, + "id": 20886, + "name": "DetailedERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22971, + "src": "5544:13:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_DetailedERC20_$22971_$", + "typeString": "type(contract DetailedERC20)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5544:40:59" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 20892, + "name": "_polymathRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20884, + "src": "5605:17:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 20893, + "modifierName": { + "argumentTypes": null, + "id": 20891, + "name": "RegistryUpdater", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 676, + "src": "5589:15:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_RegistryUpdater_$676_$", + "typeString": "type(contract RegistryUpdater)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5589:34:59" + } + ], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 20885, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20874, + "name": "_name", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5366:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20873, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "5366:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20876, + "name": "_symbol", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5388:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20875, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "5388:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20878, + "name": "_decimals", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5412:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20877, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "5412:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20880, + "name": "_granularity", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5437:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20879, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5437:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20882, + "name": "_tokenDetails", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5467:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20881, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "5467:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20884, + "name": "_polymathRegistry", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5497:25:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20883, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5497:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5356:172:59" + }, + "payable": false, + "returnParameters": { + "id": 20894, + "nodeType": "ParameterList", + "parameters": [], + "src": "5628:0:59" + }, + "scope": 22534, + "src": "5344:770:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 20969, + "nodeType": "Block", + "src": "6652:69:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20963, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20949, + "src": "6673:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 20964, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20951, + "src": "6689:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "argumentTypes": null, + "id": 20965, + "name": "_maxCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20953, + "src": "6696:8:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 20966, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20955, + "src": "6706:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 20962, + "name": "_addModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21079, + "src": "6662:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (address,bytes memory,uint256,uint256)" + } + }, + "id": 20967, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6662:52:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20968, + "nodeType": "ExpressionStatement", + "src": "6662:52:59" + } + ] + }, + "documentation": "@notice Function used to attach the module in security token\n@param _moduleFactory Contract address of the module factory that needs to be attached\n@param _data Data used for the intialization of the module factory variables\n@param _maxCost Maximum cost of the Module factory\n@param _budget Budget of the Module factory", + "id": 20970, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 20958, + "modifierName": { + "argumentTypes": null, + "id": 20957, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "6629:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "6629:9:59" + }, + { + "arguments": null, + "id": 20960, + "modifierName": { + "argumentTypes": null, + "id": 20959, + "name": "nonReentrant", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22589, + "src": "6639:12:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "6639:12:59" + } + ], + "name": "addModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 20956, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20949, + "name": "_moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6519:22:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20948, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6519:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20951, + "name": "_data", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6551:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 20950, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "6551:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20953, + "name": "_maxCost", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6572:16:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20952, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6572:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20955, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6598:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20954, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6598:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6509:110:59" + }, + "payable": false, + "returnParameters": { + "id": 20961, + "nodeType": "ParameterList", + "parameters": [], + "src": "6652:0:59" + }, + "scope": 22534, + "src": "6491:230:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 21078, + "nodeType": "Block", + "src": "7506:1172:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20985, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "7628:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20982, + "name": "moduleRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 609, + "src": "7602:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 20981, + "name": "IModuleRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9915, + "src": "7586:15:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModuleRegistry_$9915_$", + "typeString": "type(contract IModuleRegistry)" + } + }, + "id": 20983, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7586:31:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleRegistry_$9915", + "typeString": "contract IModuleRegistry" + } + }, + "id": 20984, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "useModule", + "nodeType": "MemberAccess", + "referencedDeclaration": 9899, + "src": "7586:41:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$returns$__$", + "typeString": "function (address) external" + } + }, + "id": 20986, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7586:57:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20987, + "nodeType": "ExpressionStatement", + "src": "7586:57:59" + }, + { + "assignments": [ + 20989 + ], + "declarations": [ + { + "constant": false, + "id": 20989, + "name": "moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7653:28:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + }, + "typeName": { + "contractScope": null, + "id": 20988, + "name": "IModuleFactory", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 9892, + "src": "7653:14:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20993, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20991, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "7699:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 20990, + "name": "IModuleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9892, + "src": "7684:14:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModuleFactory_$9892_$", + "typeString": "type(contract IModuleFactory)" + } + }, + "id": 20992, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7684:30:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7653:61:59" + }, + { + "assignments": [ + 20995 + ], + "declarations": [ + { + "constant": false, + "id": 20995, + "name": "moduleType", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7724:16:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20994, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "7724:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20999, + "initialValue": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "id": 20996, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "7743:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 20997, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getType", + "nodeType": "MemberAccess", + "referencedDeclaration": 9747, + "src": "7743:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint8_$", + "typeString": "function () view external returns (uint8)" + } + }, + "id": 20998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7743:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7724:42:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21006, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21001, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "7784:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21003, + "indexExpression": { + "argumentTypes": null, + "id": 21002, + "name": "moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20995, + "src": "7792:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7784:19:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21004, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7784:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 21005, + "name": "MAX_MODULES", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20679, + "src": "7813:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "7784:40:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4c696d6974206f66204d4158204d4f44554c45532069732072656163686564", + "id": 21007, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7826:33:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_22dca6cc98b2f56663821f48152354d934949af366941128c128092fc385789b", + "typeString": "literal_string \"Limit of MAX MODULES is reached\"" + }, + "value": "Limit of MAX MODULES is reached" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_22dca6cc98b2f56663821f48152354d934949af366941128c128092fc385789b", + "typeString": "literal_string \"Limit of MAX MODULES is reached\"" + } + ], + "id": 21000, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "7776:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21008, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7776:84:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21009, + "nodeType": "ExpressionStatement", + "src": "7776:84:59" + }, + { + "assignments": [ + 21011 + ], + "declarations": [ + { + "constant": false, + "id": 21011, + "name": "moduleCost", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7870:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21010, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7870:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21015, + "initialValue": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "id": 21012, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "7891:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 21013, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "setupCost", + "nodeType": "MemberAccess", + "referencedDeclaration": 9665, + "src": "7891:23:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + } + }, + "id": 21014, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7891:25:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7870:46:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21019, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21017, + "name": "moduleCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21011, + "src": "7934:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 21018, + "name": "_maxCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20976, + "src": "7948:8:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7934:22:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d617820436f737420697320616c776179732062652067726561746572207468616e206d6f64756c6520636f7374", + "id": 21020, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7958:48:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_90bdcbd1eae82678b05a05785b42cb078a37b23efb50052519b8f8f8daee9e4f", + "typeString": "literal_string \"Max Cost is always be greater than module cost\"" + }, + "value": "Max Cost is always be greater than module cost" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_90bdcbd1eae82678b05a05785b42cb078a37b23efb50052519b8f8f8daee9e4f", + "typeString": "literal_string \"Max Cost is always be greater than module cost\"" + } + ], + "id": 21016, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "7926:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21021, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7926:81:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21022, + "nodeType": "ExpressionStatement", + "src": "7926:81:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21028, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "8083:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21029, + "name": "moduleCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21011, + "src": "8099:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21025, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "8064:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21024, + "name": "ERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23014, + "src": "8058:5:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ERC20_$23014_$", + "typeString": "type(contract ERC20)" + } + }, + "id": 21026, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8058:16:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$23014", + "typeString": "contract ERC20" + } + }, + "id": 21027, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "approve", + "nodeType": "MemberAccess", + "referencedDeclaration": 23005, + "src": "8058:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21030, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8058:52:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4e6f742061626c6520746f20617070726f766520746865206d6f64756c6520636f7374", + "id": 21031, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8112:37:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_11ebda84b718c1e17032ff96739c6d6235706a8e1578218e5e6f4a7e2005eab5", + "typeString": "literal_string \"Not able to approve the module cost\"" + }, + "value": "Not able to approve the module cost" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_11ebda84b718c1e17032ff96739c6d6235706a8e1578218e5e6f4a7e2005eab5", + "typeString": "literal_string \"Not able to approve the module cost\"" + } + ], + "id": 21023, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "8050:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21032, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8050:100:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21033, + "nodeType": "ExpressionStatement", + "src": "8050:100:59" + }, + { + "assignments": [ + 21035 + ], + "declarations": [ + { + "constant": false, + "id": 21035, + "name": "module", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "8210:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21034, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8210:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21040, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21038, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20974, + "src": "8248:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 21036, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "8227:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 21037, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "deploy", + "nodeType": "MemberAccess", + "referencedDeclaration": 9742, + "src": "8227:20:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_bytes_memory_ptr_$returns$_t_address_$", + "typeString": "function (bytes memory) external returns (address)" + } + }, + "id": 21039, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8227:27:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "8210:44:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21046, + "name": "module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21035, + "src": "8330:6:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21047, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20978, + "src": "8338:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21043, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "8311:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21042, + "name": "ERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23014, + "src": "8305:5:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ERC20_$23014_$", + "typeString": "type(contract ERC20)" + } + }, + "id": 21044, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8305:16:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$23014", + "typeString": "contract ERC20" + } + }, + "id": 21045, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "approve", + "nodeType": "MemberAccess", + "referencedDeclaration": 23005, + "src": "8305:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21048, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8305:41:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4e6f742061626c6520746f20617070726f76652074686520627564676574", + "id": 21049, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8348:32:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_524ae74447c5c157d26c458a70f19c36827828baf5b9a2964a7996292f367fcf", + "typeString": "literal_string \"Not able to approve the budget\"" + }, + "value": "Not able to approve the budget" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_524ae74447c5c157d26c458a70f19c36827828baf5b9a2964a7996292f367fcf", + "typeString": "literal_string \"Not able to approve the budget\"" + } + ], + "id": 21041, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "8297:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21050, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8297:84:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21051, + "nodeType": "ExpressionStatement", + "src": "8297:84:59" + }, + { + "assignments": [ + 21053 + ], + "declarations": [ + { + "constant": false, + "id": 21053, + "name": "moduleName", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "8433:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21052, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8433:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21057, + "initialValue": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "id": 21054, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "8454:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 21055, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getName", + "nodeType": "MemberAccess", + "referencedDeclaration": 9752, + "src": "8454:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_bytes32_$", + "typeString": "function () view external returns (bytes32)" + } + }, + "id": 21056, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8454:23:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "8433:44:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21063, + "name": "moduleName", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21053, + "src": "8523:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 21064, + "name": "module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21035, + "src": "8535:6:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21062, + "name": "ModuleData", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20648, + "src": "8512:10:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_ModuleData_$20648_storage_ptr_$", + "typeString": "type(struct SecurityToken.ModuleData storage pointer)" + } + }, + "id": 21065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8512:30:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_memory", + "typeString": "struct SecurityToken.ModuleData memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_ModuleData_$20648_memory", + "typeString": "struct SecurityToken.ModuleData memory" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21058, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "8487:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21060, + "indexExpression": { + "argumentTypes": null, + "id": 21059, + "name": "moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20995, + "src": "8495:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "8487:19:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21061, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "8487:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_struct$_ModuleData_$20648_storage_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.ModuleData storage ref) returns (uint256)" + } + }, + "id": 21066, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8487:56:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21067, + "nodeType": "ExpressionStatement", + "src": "8487:56:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21069, + "name": "moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20995, + "src": "8598:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "id": 21070, + "name": "moduleName", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21053, + "src": "8610:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 21071, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "8622:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21072, + "name": "module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21035, + "src": "8638:6:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21073, + "name": "moduleCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21011, + "src": "8646:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21074, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20978, + "src": "8658:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21075, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "8667:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21068, + "name": "LogModuleAdded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20699, + "src": "8583:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint8_$_t_bytes32_$_t_address_$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint8,bytes32,address,address,uint256,uint256,uint256)" + } + }, + "id": 21076, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8583:88:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21077, + "nodeType": "EmitStatement", + "src": "8578:93:59" + } + ] + }, + "documentation": "@notice _addModule handles the attachment (or replacement) of modules for the ST\n@dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it\n@dev to control restrictions on transfers.\n@dev You are allowed to add a new moduleType if:\n@dev - there is no existing module of that type yet added\n@dev - the last member of the module list is replacable\n@param _moduleFactory is the address of the module factory to be added\n@param _data is data packed into bytes used to further configure the module (See STO usage)\n@param _maxCost max amount of POLY willing to pay to module. (WIP)", + "id": 21079, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_addModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 20979, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20972, + "name": "_moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7425:22:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20971, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "7425:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20974, + "name": "_data", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7449:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 20973, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "7449:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20976, + "name": "_maxCost", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7462:16:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20975, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7462:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20978, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7480:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20977, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7480:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7424:72:59" + }, + "payable": false, + "returnParameters": { + "id": 20980, + "nodeType": "ParameterList", + "parameters": [], + "src": "7506:0:59" + }, + "scope": 22534, + "src": "7405:1273:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21152, + "nodeType": "Block", + "src": "8989:649:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21094, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21089, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9007:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21090, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9022:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21092, + "indexExpression": { + "argumentTypes": null, + "id": 21091, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9030:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9022:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21093, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9022:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9007:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d6f64756c6520696e64657820646f65736e277420657869737420617320706572207468652063686f6f73656e206d6f64756c652074797065", + "id": 21095, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9059:59:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2c2b71fb37297b532fe6ad2499a7624af6231a453bb6b813ec9dd531487fa7d5", + "typeString": "literal_string \"Module index doesn't exist as per the choosen module type\"" + }, + "value": "Module index doesn't exist as per the choosen module type" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2c2b71fb37297b532fe6ad2499a7624af6231a453bb6b813ec9dd531487fa7d5", + "typeString": "literal_string \"Module index doesn't exist as per the choosen module type\"" + } + ], + "id": 21088, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "8999:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21096, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8999:120:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21097, + "nodeType": "ExpressionStatement", + "src": "8999:120:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21108, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21099, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9137:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21101, + "indexExpression": { + "argumentTypes": null, + "id": 21100, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9145:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9137:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21103, + "indexExpression": { + "argumentTypes": null, + "id": 21102, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9158:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9137:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21104, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "9137:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21106, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9197:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21105, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "9189:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21107, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9189:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "9137:62:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d6f64756c6520636f6e747261637420616464726573732073686f756c64206e6f74206265203078", + "id": 21109, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9209:42:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2079f97d089efa5c6ae574cb5c749cfd9f6fe18b9702363bcb14091aec9a3ff9", + "typeString": "literal_string \"Module contract address should not be 0x\"" + }, + "value": "Module contract address should not be 0x" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2079f97d089efa5c6ae574cb5c749cfd9f6fe18b9702363bcb14091aec9a3ff9", + "typeString": "literal_string \"Module contract address should not be 0x\"" + } + ], + "id": 21098, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "9129:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21110, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9129:123:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21111, + "nodeType": "ExpressionStatement", + "src": "9129:123:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21113, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9393:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21114, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9406:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21116, + "indexExpression": { + "argumentTypes": null, + "id": 21115, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9414:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9406:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21118, + "indexExpression": { + "argumentTypes": null, + "id": 21117, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9427:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9406:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21119, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "9406:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21120, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "9456:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21112, + "name": "LogModuleRemoved", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20719, + "src": "9376:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint8_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (uint8,address,uint256)" + } + }, + "id": 21121, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9376:84:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21122, + "nodeType": "EmitStatement", + "src": "9371:89:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21138, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21123, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9470:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21126, + "indexExpression": { + "argumentTypes": null, + "id": 21124, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9478:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9470:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21127, + "indexExpression": { + "argumentTypes": null, + "id": 21125, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9491:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "9470:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21128, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9507:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21130, + "indexExpression": { + "argumentTypes": null, + "id": 21129, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9515:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9507:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21137, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21136, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21131, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9528:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21133, + "indexExpression": { + "argumentTypes": null, + "id": 21132, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9536:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9528:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21134, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9528:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21135, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9558:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9528:31:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9507:53:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "src": "9470:90:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21139, + "nodeType": "ExpressionStatement", + "src": "9470:90:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21150, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21140, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9570:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21142, + "indexExpression": { + "argumentTypes": null, + "id": 21141, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9578:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9570:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21143, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9570:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21149, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21144, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9600:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21146, + "indexExpression": { + "argumentTypes": null, + "id": 21145, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9608:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9600:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21147, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9600:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21148, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9630:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9600:31:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9570:61:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21151, + "nodeType": "ExpressionStatement", + "src": "9570:61:59" + } + ] + }, + "documentation": "@notice Removes a module attached to the SecurityToken\n@param _moduleType is which type of module we are trying to remove\n@param _moduleIndex is the index of the module within the chosen type", + "id": 21153, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21086, + "modifierName": { + "argumentTypes": null, + "id": 21085, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "8979:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "8979:9:59" + } + ], + "name": "removeModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21084, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21081, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21153, + "src": "8931:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21080, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "8931:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21083, + "name": "_moduleIndex", + "nodeType": "VariableDeclaration", + "scope": 21153, + "src": "8950:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21082, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "8950:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "8930:39:59" + }, + "payable": false, + "returnParameters": { + "id": 21087, + "nodeType": "ParameterList", + "parameters": [], + "src": "8989:0:59" + }, + "scope": 22534, + "src": "8909:729:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 21193, + "nodeType": "Block", + "src": "10003:277:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21169, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21164, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10017:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21166, + "indexExpression": { + "argumentTypes": null, + "id": 21165, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21155, + "src": "10025:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10017:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21167, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10017:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21168, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10047:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10017:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 21191, + "nodeType": "Block", + "src": "10225:48:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "hexValue": "", + "id": 21185, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10247:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21187, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10259:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21186, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "10251:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21188, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10251:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21189, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10246:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_$_t_address_$", + "typeString": "tuple(literal_string \"\",address)" + } + }, + "functionReturnParameters": 21163, + "id": 21190, + "nodeType": "Return", + "src": "10239:23:59" + } + ] + }, + "id": 21192, + "nodeType": "IfStatement", + "src": "10013:260:59", + "trueBody": { + "id": 21184, + "nodeType": "Block", + "src": "10050:169:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21170, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10089:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21172, + "indexExpression": { + "argumentTypes": null, + "id": 21171, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21155, + "src": "10097:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10089:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21174, + "indexExpression": { + "argumentTypes": null, + "id": 21173, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21157, + "src": "10110:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10089:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21175, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "name", + "nodeType": "MemberAccess", + "referencedDeclaration": 20645, + "src": "10089:39:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21176, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10146:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21178, + "indexExpression": { + "argumentTypes": null, + "id": 21177, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21155, + "src": "10154:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10146:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21180, + "indexExpression": { + "argumentTypes": null, + "id": 21179, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21157, + "src": "10167:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10146:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21181, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "10146:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21182, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10071:137:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$", + "typeString": "tuple(bytes32,address)" + } + }, + "functionReturnParameters": 21163, + "id": 21183, + "nodeType": "Return", + "src": "10064:144:59" + } + ] + } + } + ] + }, + "documentation": "@notice Returns module list for a module type\n@param _moduleType is which type of module we are trying to get\n@param _moduleIndex is the index of the module within the chosen type\n@return bytes32\n@return address", + "id": 21194, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21158, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21155, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9926:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21154, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "9926:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21157, + "name": "_moduleIndex", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9945:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21156, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "9945:4:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9925:38:59" + }, + "payable": false, + "returnParameters": { + "id": 21163, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21160, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9985:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21159, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9985:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21162, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9994:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21161, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9994:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9984:18:59" + }, + "scope": 22534, + "src": "9907:373:59", + "stateMutability": "view", + "superFunction": 10059, + "visibility": "public" + }, + { + "body": { + "id": 21265, + "nodeType": "Block", + "src": "10665:480:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21210, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21205, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10679:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21207, + "indexExpression": { + "argumentTypes": null, + "id": 21206, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10687:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10679:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21208, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10679:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21209, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10709:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10679:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 21263, + "nodeType": "Block", + "src": "11091:48:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "hexValue": "", + "id": 21257, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11113:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21259, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11125:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21258, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "11117:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21260, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11117:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21261, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "11112:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_$_t_address_$", + "typeString": "tuple(literal_string \"\",address)" + } + }, + "functionReturnParameters": 21204, + "id": 21262, + "nodeType": "Return", + "src": "11105:23:59" + } + ] + }, + "id": 21264, + "nodeType": "IfStatement", + "src": "10675:464:59", + "trueBody": { + "id": 21256, + "nodeType": "Block", + "src": "10712:373:59", + "statements": [ + { + "body": { + "id": 21248, + "nodeType": "Block", + "src": "10784:254:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 21231, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21224, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10806:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21226, + "indexExpression": { + "argumentTypes": null, + "id": 21225, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10814:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10806:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21228, + "indexExpression": { + "argumentTypes": null, + "id": 21227, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10827:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10806:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21229, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "name", + "nodeType": "MemberAccess", + "referencedDeclaration": 20645, + "src": "10806:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 21230, + "name": "_name", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21198, + "src": "10838:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "10806:37:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21247, + "nodeType": "IfStatement", + "src": "10802:222:59", + "trueBody": { + "id": 21246, + "nodeType": "Block", + "src": "10845:179:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21232, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10896:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21234, + "indexExpression": { + "argumentTypes": null, + "id": 21233, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10904:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10896:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21236, + "indexExpression": { + "argumentTypes": null, + "id": 21235, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10917:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10896:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21237, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "name", + "nodeType": "MemberAccess", + "referencedDeclaration": 20645, + "src": "10896:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21238, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10948:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21240, + "indexExpression": { + "argumentTypes": null, + "id": 21239, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10956:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10948:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21242, + "indexExpression": { + "argumentTypes": null, + "id": 21241, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10969:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10948:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21243, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "10948:37:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21244, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10872:133:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$", + "typeString": "tuple(bytes32,address)" + } + }, + "functionReturnParameters": 21204, + "id": 21245, + "nodeType": "Return", + "src": "10865:140:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21220, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21215, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10746:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21216, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10750:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21218, + "indexExpression": { + "argumentTypes": null, + "id": 21217, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10758:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10750:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21219, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10750:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10746:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21249, + "initializationExpression": { + "assignments": [ + 21212 + ], + "declarations": [ + { + "constant": false, + "id": 21212, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10731:9:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21211, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10731:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21214, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 21213, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10743:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "10731:13:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 21222, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "10779:3:59", + "subExpression": { + "argumentTypes": null, + "id": 21221, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10779:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21223, + "nodeType": "ExpressionStatement", + "src": "10779:3:59" + }, + "nodeType": "ForStatement", + "src": "10726:312:59" + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "hexValue": "", + "id": 21250, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11059:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21252, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11071:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21251, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "11063:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21253, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11063:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21254, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "11058:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_$_t_address_$", + "typeString": "tuple(literal_string \"\",address)" + } + }, + "functionReturnParameters": 21204, + "id": 21255, + "nodeType": "Return", + "src": "11051:23:59" + } + ] + } + } + ] + }, + "documentation": "@notice returns module list for a module name - will return first match\n@param _moduleType is which type of module we are trying to get\n@param _name is the name of the module within the chosen type\n@return bytes32\n@return address", + "id": 21266, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getModuleByName", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21199, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21196, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10592:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21195, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "10592:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21198, + "name": "_name", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10611:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21197, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10611:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10591:34:59" + }, + "payable": false, + "returnParameters": { + "id": 21204, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21201, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10647:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21200, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10647:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21203, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10656:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21202, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "10656:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10646:18:59" + }, + "scope": 22534, + "src": "10567:578:59", + "stateMutability": "view", + "superFunction": 10070, + "visibility": "public" + }, + { + "body": { + "id": 21284, + "nodeType": "Block", + "src": "11460:92:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21278, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "11504:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21279, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21268, + "src": "11511:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21275, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "11484:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21274, + "name": "ERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23014, + "src": "11478:5:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ERC20_$23014_$", + "typeString": "type(contract ERC20)" + } + }, + "id": 21276, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11478:16:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$23014", + "typeString": "contract ERC20" + } + }, + "id": 21277, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "transfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 23037, + "src": "11478:25:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21280, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11478:41:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e2d73756666696369656e742062616c616e6365", + "id": 21281, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11521:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_30a1bb60a0c6caf3e6f6f7b8691b64b76aa0d2ff7478fc897cfd6f5a122b1b2b", + "typeString": "literal_string \"In-sufficient balance\"" + }, + "value": "In-sufficient balance" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_30a1bb60a0c6caf3e6f6f7b8691b64b76aa0d2ff7478fc897cfd6f5a122b1b2b", + "typeString": "literal_string \"In-sufficient balance\"" + } + ], + "id": 21273, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "11470:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21282, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11470:75:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21283, + "nodeType": "ExpressionStatement", + "src": "11470:75:59" + } + ] + }, + "documentation": "@notice allows the owner to withdraw unspent POLY stored by them on the ST.\n@dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee.\n@param _amount amount of POLY to withdraw", + "id": 21285, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21271, + "modifierName": { + "argumentTypes": null, + "id": 21270, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "11450:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "11450:9:59" + } + ], + "name": "withdrawPoly", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21269, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21268, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 21285, + "src": "11426:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21267, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11426:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "11425:17:59" + }, + "payable": false, + "returnParameters": { + "id": 21272, + "nodeType": "ParameterList", + "parameters": [], + "src": "11460:0:59" + }, + "scope": 22534, + "src": "11404:148:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21385, + "nodeType": "Block", + "src": "11852:835:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 21299, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21297, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "11870:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21298, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11885:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11870:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d6f64756c6520747970652063616e6e6f74206265207a65726f", + "id": 21300, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11888:28:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_22e5fe8e01473d297e25a2a1aee7f758126121ff74d7fafb2b5bccf21dbd9682", + "typeString": "literal_string \"Module type cannot be zero\"" + }, + "value": "Module type cannot be zero" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_22e5fe8e01473d297e25a2a1aee7f758126121ff74d7fafb2b5bccf21dbd9682", + "typeString": "literal_string \"Module type cannot be zero\"" + } + ], + "id": 21296, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "11862:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21301, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11862:55:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21302, + "nodeType": "ExpressionStatement", + "src": "11862:55:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21309, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21304, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "11935:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21305, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "11950:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21307, + "indexExpression": { + "argumentTypes": null, + "id": 21306, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "11958:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "11950:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21308, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11950:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11935:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e636f727272656374206d6f64756c6520696e646578", + "id": 21310, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11979:25:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_246e30dbb9a00692967b4085cbb5fa5d23ee41ba746d906437cdc6324b067ad6", + "typeString": "literal_string \"Incorrrect module index\"" + }, + "value": "Incorrrect module index" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_246e30dbb9a00692967b4085cbb5fa5d23ee41ba746d906437cdc6324b067ad6", + "typeString": "literal_string \"Incorrrect module index\"" + } + ], + "id": 21303, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "11927:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21311, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11927:78:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21312, + "nodeType": "ExpressionStatement", + "src": "11927:78:59" + }, + { + "assignments": [ + 21314 + ], + "declarations": [ + { + "constant": false, + "id": 21314, + "name": "_currentAllowance", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "12015:25:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21313, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "12015:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21329, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21320, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23373, + "src": "12079:4:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SecurityToken_$22534", + "typeString": "contract SecurityToken" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_SecurityToken_$22534", + "typeString": "contract SecurityToken" + } + ], + "id": 21319, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12071:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21321, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12071:13:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21322, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12086:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21324, + "indexExpression": { + "argumentTypes": null, + "id": 21323, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12094:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12086:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21326, + "indexExpression": { + "argumentTypes": null, + "id": 21325, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12107:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12086:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21327, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12086:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21316, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "12050:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21315, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9492, + "src": "12043:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC20_$9492_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 21317, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12043:17:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IERC20_$9492", + "typeString": "contract IERC20" + } + }, + "id": 21318, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "allowance", + "nodeType": "MemberAccess", + "referencedDeclaration": 22985, + "src": "12043:27:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_address_$_t_address_$returns$_t_uint256_$", + "typeString": "function (address,address) view external returns (uint256)" + } + }, + "id": 21328, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12043:92:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12015:120:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21332, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21330, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12149:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 21331, + "name": "_currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21314, + "src": "12159:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12149:27:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 21372, + "nodeType": "Block", + "src": "12378:194:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21358, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12435:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21360, + "indexExpression": { + "argumentTypes": null, + "id": 21359, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12443:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12435:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21362, + "indexExpression": { + "argumentTypes": null, + "id": 21361, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12456:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12435:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21363, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12435:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21366, + "name": "_currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21314, + "src": "12497:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21364, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12485:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21365, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "12485:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21367, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12485:30:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21355, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "12407:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21354, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9492, + "src": "12400:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC20_$9492_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 21356, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12400:17:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IERC20_$9492", + "typeString": "contract IERC20" + } + }, + "id": 21357, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "increaseApproval", + "nodeType": "MemberAccess", + "referencedDeclaration": 9491, + "src": "12400:34:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21368, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12400:116:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e73756666696369656e742062616c616e636520746f20696e637265617365417070726f76616c", + "id": 21369, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12518:42:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_3b00cfda6eac0d5cac672a125e339ba8d9ee08603d0d23f305665757678226dc", + "typeString": "literal_string \"Insufficient balance to increaseApproval\"" + }, + "value": "Insufficient balance to increaseApproval" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_3b00cfda6eac0d5cac672a125e339ba8d9ee08603d0d23f305665757678226dc", + "typeString": "literal_string \"Insufficient balance to increaseApproval\"" + } + ], + "id": 21353, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "12392:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21370, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12392:169:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21371, + "nodeType": "ExpressionStatement", + "src": "12392:169:59" + } + ] + }, + "id": 21373, + "nodeType": "IfStatement", + "src": "12145:427:59", + "trueBody": { + "id": 21352, + "nodeType": "Block", + "src": "12178:194:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21338, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12235:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21340, + "indexExpression": { + "argumentTypes": null, + "id": 21339, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12243:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12235:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21342, + "indexExpression": { + "argumentTypes": null, + "id": 21341, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12256:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12235:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21343, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12235:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21346, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12307:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21344, + "name": "_currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21314, + "src": "12285:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21345, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "12285:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21347, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12285:30:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21335, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "12207:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21334, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9492, + "src": "12200:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC20_$9492_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 21336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12200:17:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IERC20_$9492", + "typeString": "contract IERC20" + } + }, + "id": 21337, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "decreaseApproval", + "nodeType": "MemberAccess", + "referencedDeclaration": 9482, + "src": "12200:34:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21348, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12200:116:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e73756666696369656e742062616c616e636520746f206465637265617365417070726f76616c", + "id": 21349, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12318:42:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f1a242750d5ca62923d53471e92c457415e83478e55fbb541dc14993793b903d", + "typeString": "literal_string \"Insufficient balance to decreaseApproval\"" + }, + "value": "Insufficient balance to decreaseApproval" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f1a242750d5ca62923d53471e92c457415e83478e55fbb541dc14993793b903d", + "typeString": "literal_string \"Insufficient balance to decreaseApproval\"" + } + ], + "id": 21333, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "12192:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21350, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12192:169:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21351, + "nodeType": "ExpressionStatement", + "src": "12192:169:59" + } + ] + } + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21375, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12609:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21376, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12622:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21378, + "indexExpression": { + "argumentTypes": null, + "id": 21377, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12630:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12622:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21380, + "indexExpression": { + "argumentTypes": null, + "id": 21379, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12643:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12622:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21381, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12622:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21382, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12672:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21374, + "name": "LogModuleBudgetChanged", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20727, + "src": "12586:22:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint8_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (uint8,address,uint256)" + } + }, + "id": 21383, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12586:94:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21384, + "nodeType": "EmitStatement", + "src": "12581:99:59" + } + ] + }, + "documentation": "@notice allows owner to approve more POLY to one of the modules\n@param _moduleType module type\n@param _moduleIndex module index\n@param _budget new budget", + "id": 21386, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21294, + "modifierName": { + "argumentTypes": null, + "id": 21293, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "11842:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "11842:9:59" + } + ], + "name": "changeModuleBudget", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21292, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21287, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "11779:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21286, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "11779:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21289, + "name": "_moduleIndex", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "11798:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21288, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "11798:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21291, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "11818:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21290, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11818:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "11778:56:59" + }, + "payable": false, + "returnParameters": { + "id": 21295, + "nodeType": "ParameterList", + "parameters": [], + "src": "11852:0:59" + }, + "scope": 22534, + "src": "11751:936:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21402, + "nodeType": "Block", + "src": "12867:116:59", + "statements": [ + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21394, + "name": "tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9948, + "src": "12904:12:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + { + "argumentTypes": null, + "id": 21395, + "name": "_newTokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21388, + "src": "12918:16:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "id": 21393, + "name": "LogUpdateTokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20705, + "src": "12882:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (string memory,string memory)" + } + }, + "id": 21396, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12882:53:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21397, + "nodeType": "EmitStatement", + "src": "12877:58:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21398, + "name": "tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9948, + "src": "12945:12:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 21399, + "name": "_newTokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21388, + "src": "12960:16:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + "src": "12945:31:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "id": 21401, + "nodeType": "ExpressionStatement", + "src": "12945:31:59" + } + ] + }, + "documentation": "@notice change the tokenDetails\n@param _newTokenDetails New token details", + "id": 21403, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21391, + "modifierName": { + "argumentTypes": null, + "id": 21390, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "12857:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "12857:9:59" + } + ], + "name": "updateTokenDetails", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21389, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21388, + "name": "_newTokenDetails", + "nodeType": "VariableDeclaration", + "scope": 21403, + "src": "12825:23:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 21387, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "12825:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12824:25:59" + }, + "payable": false, + "returnParameters": { + "id": 21392, + "nodeType": "ParameterList", + "parameters": [], + "src": "12867:0:59" + }, + "scope": 22534, + "src": "12797:186:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21426, + "nodeType": "Block", + "src": "13182:170:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21413, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21411, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21405, + "src": "13200:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21412, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13216:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13200:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4772616e756c61726974792063616e206e6f742062652030", + "id": 21414, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13219:26:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2d4731cbc00328ab390123e785f8142f724cfe715c557f1d89e769da378906ce", + "typeString": "literal_string \"Granularity can not be 0\"" + }, + "value": "Granularity can not be 0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2d4731cbc00328ab390123e785f8142f724cfe715c557f1d89e769da378906ce", + "typeString": "literal_string \"Granularity can not be 0\"" + } + ], + "id": 21410, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "13192:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21415, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13192:54:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21416, + "nodeType": "ExpressionStatement", + "src": "13192:54:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21418, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "13283:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21419, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21405, + "src": "13296:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21417, + "name": "LogGranularityChanged", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20711, + "src": "13261:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 21420, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13261:48:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21421, + "nodeType": "EmitStatement", + "src": "13256:53:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21424, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21422, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "13319:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 21423, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21405, + "src": "13333:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13319:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21425, + "nodeType": "ExpressionStatement", + "src": "13319:26:59" + } + ] + }, + "documentation": "@notice allows owner to change token granularity\n@param _granularity granularity level of the token", + "id": 21427, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21408, + "modifierName": { + "argumentTypes": null, + "id": 21407, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "13172:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "13172:9:59" + } + ], + "name": "changeGranularity", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21406, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21405, + "name": "_granularity", + "nodeType": "VariableDeclaration", + "scope": 21427, + "src": "13143:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21404, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13143:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13142:22:59" + }, + "payable": false, + "returnParameters": { + "id": 21409, + "nodeType": "ParameterList", + "parameters": [], + "src": "13182:0:59" + }, + "scope": 22534, + "src": "13116:236:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21509, + "nodeType": "Block", + "src": "13635:603:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21444, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21438, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21436, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21433, + "src": "13650:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21437, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13660:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13650:11:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21439, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13649:13:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21442, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21440, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21429, + "src": "13667:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 21441, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "13676:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13667:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21443, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13666:14:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13649:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21447, + "nodeType": "IfStatement", + "src": "13645:68:59", + "trueBody": { + "id": 21446, + "nodeType": "Block", + "src": "13682:31:59", + "statements": [ + { + "expression": null, + "functionReturnParameters": 21435, + "id": 21445, + "nodeType": "Return", + "src": "13696:7:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21460, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21452, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21449, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "13793:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21448, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "13783:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21450, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13783:14:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21451, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13801:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13783:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21453, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13782:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21458, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21454, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "13808:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21456, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13823:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21455, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "13815:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21457, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13815:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13808:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21459, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13807:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13782:44:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21469, + "nodeType": "IfStatement", + "src": "13778:111:59", + "trueBody": { + "id": 21468, + "nodeType": "Block", + "src": "13828:61:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21466, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21461, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "13842:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 21464, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13876:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "expression": { + "argumentTypes": null, + "id": 21462, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "13858:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21463, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "13858:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21465, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13858:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13842:36:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21467, + "nodeType": "ExpressionStatement", + "src": "13842:36:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21474, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21470, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21433, + "src": "13964:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21472, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21429, + "src": "13984:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21471, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "13974:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21473, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13974:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13964:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21483, + "nodeType": "IfStatement", + "src": "13960:93:59", + "trueBody": { + "id": 21482, + "nodeType": "Block", + "src": "13992:61:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21480, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21475, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "14006:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 21478, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14040:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "expression": { + "argumentTypes": null, + "id": 21476, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "14022:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21477, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "14022:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21479, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14022:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14006:36:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21481, + "nodeType": "ExpressionStatement", + "src": "14006:36:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21494, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21487, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "14102:20:59", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21484, + "name": "investorListed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20683, + "src": "14103:14:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + } + }, + "id": 21486, + "indexExpression": { + "argumentTypes": null, + "id": 21485, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14118:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14103:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21492, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21488, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14127:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21490, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14142:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21489, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "14134:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21491, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14134:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "14127:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21493, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14126:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "14102:43:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21508, + "nodeType": "IfStatement", + "src": "14098:133:59", + "trueBody": { + "id": 21507, + "nodeType": "Block", + "src": "14147:84:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21498, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14176:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "argumentTypes": null, + "id": 21495, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14161:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21497, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14161:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) returns (uint256)" + } + }, + "id": 21499, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14161:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21500, + "nodeType": "ExpressionStatement", + "src": "14161:19:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21505, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21501, + "name": "investorListed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20683, + "src": "14194:14:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + } + }, + "id": 21503, + "indexExpression": { + "argumentTypes": null, + "id": 21502, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14209:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "14194:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21504, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14216:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "14194:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21506, + "nodeType": "ExpressionStatement", + "src": "14194:26:59" + } + ] + } + } + ] + }, + "documentation": "@notice keeps track of the number of non-zero token holders\n@param _from sender of transfer\n@param _to receiver of transfer\n@param _value value of transfer", + "id": 21510, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustInvestorCount", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21434, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21429, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 21510, + "src": "13582:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21428, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13582:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21431, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21510, + "src": "13597:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21430, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13597:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21433, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 21510, + "src": "13610:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21432, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13610:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13581:44:59" + }, + "payable": false, + "returnParameters": { + "id": 21435, + "nodeType": "ParameterList", + "parameters": [], + "src": "13635:0:59" + }, + "scope": 22534, + "src": "13553:685:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21579, + "nodeType": "Block", + "src": "14676:356:59", + "statements": [ + { + "body": { + "id": 21577, + "nodeType": "Block", + "src": "14771:255:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21550, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21540, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21537, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14790:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21538, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14794:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21539, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14794:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14790:20:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21541, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14789:22:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21548, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21543, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14826:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21545, + "indexExpression": { + "argumentTypes": null, + "id": 21544, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14836:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14826:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21542, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "14816:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21546, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14816:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21547, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14843:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "14816:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21549, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14815:30:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "14789:56:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21576, + "nodeType": "IfStatement", + "src": "14785:231:59", + "trueBody": { + "id": 21575, + "nodeType": "Block", + "src": "14847:169:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21557, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21551, + "name": "investorListed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20683, + "src": "14865:14:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + } + }, + "id": 21555, + "indexExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21552, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14880:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21554, + "indexExpression": { + "argumentTypes": null, + "id": 21553, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14890:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14880:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "14865:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21556, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14896:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "14865:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21558, + "nodeType": "ExpressionStatement", + "src": "14865:36:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21568, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21559, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14919:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21561, + "indexExpression": { + "argumentTypes": null, + "id": 21560, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14929:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "14919:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21562, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14934:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21567, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21566, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21563, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14944:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21564, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14944:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21565, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14963:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "14944:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14934:31:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "14919:46:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 21569, + "nodeType": "ExpressionStatement", + "src": "14919:46:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21573, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "--", + "prefix": false, + "src": "14983:18:59", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21570, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14983:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21572, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14983:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21574, + "nodeType": "ExpressionStatement", + "src": "14983:18:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21533, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21523, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14711:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21528, + "name": "_iters", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21514, + "src": "14738:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21526, + "name": "_start", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21512, + "src": "14727:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21527, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "14727:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21529, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14727:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21530, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14747:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21531, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14747:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21524, + "name": "Math", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22661, + "src": "14715:4:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Math_$22661_$", + "typeString": "type(library Math)" + } + }, + "id": 21525, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "min256", + "nodeType": "MemberAccess", + "referencedDeclaration": 22660, + "src": "14715:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21532, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14715:49:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14711:53:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21578, + "initializationExpression": { + "assignments": [ + 21520 + ], + "declarations": [ + { + "constant": false, + "id": 21520, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 21580, + "src": "14691:9:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21519, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14691:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21522, + "initialValue": { + "argumentTypes": null, + "id": 21521, + "name": "_start", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21512, + "src": "14703:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "14691:18:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 21535, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "14766:3:59", + "subExpression": { + "argumentTypes": null, + "id": 21534, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14766:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21536, + "nodeType": "ExpressionStatement", + "src": "14766:3:59" + }, + "nodeType": "ForStatement", + "src": "14686:340:59" + } + ] + }, + "documentation": "@notice removes addresses with zero balances from the investors list\n@param _start Index in investor list at which to start removing zero balances\n@param _iters Max number of iterations of the for loop\nNB - pruning this list will mean you may not be able to iterate over investors on-chain as of a historical checkpoint", + "id": 21580, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21517, + "modifierName": { + "argumentTypes": null, + "id": 21516, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "14666:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "14666:9:59" + } + ], + "name": "pruneInvestors", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21515, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21512, + "name": "_start", + "nodeType": "VariableDeclaration", + "scope": 21580, + "src": "14627:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21511, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14627:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21514, + "name": "_iters", + "nodeType": "VariableDeclaration", + "scope": 21580, + "src": "14643:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21513, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14643:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "14626:32:59" + }, + "payable": false, + "returnParameters": { + "id": 21518, + "nodeType": "ParameterList", + "parameters": [], + "src": "14676:0:59" + }, + "scope": 22534, + "src": "14603:429:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21588, + "nodeType": "Block", + "src": "15289:40:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21585, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "15306:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21586, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "15306:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 21584, + "id": 21587, + "nodeType": "Return", + "src": "15299:23:59" + } + ] + }, + "documentation": "@notice gets length of investors array\nNB - this length may differ from investorCount if list has not been pruned of zero balance investors\n@return length", + "id": 21589, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getInvestorsLength", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21581, + "nodeType": "ParameterList", + "parameters": [], + "src": "15257:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21584, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21583, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21589, + "src": "15280:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21582, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "15280:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "15279:9:59" + }, + "scope": 22534, + "src": "15230:99:59", + "stateMutability": "view", + "superFunction": 10096, + "visibility": "public" + }, + { + "body": { + "id": 21608, + "nodeType": "Block", + "src": "15435:102:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21596, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "15453:7:59", + "subExpression": { + "argumentTypes": null, + "id": 21595, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15454:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21594, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "15445:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21597, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15445:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21598, + "nodeType": "ExpressionStatement", + "src": "15445:16:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21601, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21599, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15471:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21600, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15480:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "15471:13:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21602, + "nodeType": "ExpressionStatement", + "src": "15471:13:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21604, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15518:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "id": 21605, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "15526:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21603, + "name": "LogFreezeTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20733, + "src": "15499:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$_t_uint256_$returns$__$", + "typeString": "function (bool,uint256)" + } + }, + "id": 21606, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15499:31:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21607, + "nodeType": "EmitStatement", + "src": "15494:36:59" + } + ] + }, + "documentation": "@notice freeze all the transfers", + "id": 21609, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21592, + "modifierName": { + "argumentTypes": null, + "id": 21591, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "15425:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "15425:9:59" + } + ], + "name": "freezeTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21590, + "nodeType": "ParameterList", + "parameters": [], + "src": "15415:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21593, + "nodeType": "ParameterList", + "parameters": [], + "src": "15435:0:59" + }, + "scope": 22534, + "src": "15391:146:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21627, + "nodeType": "Block", + "src": "15648:102:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21615, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15666:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21614, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "15658:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21616, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15658:15:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21617, + "nodeType": "ExpressionStatement", + "src": "15658:15:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21620, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21618, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15683:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21619, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15692:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "15683:14:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21621, + "nodeType": "ExpressionStatement", + "src": "15683:14:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21623, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15731:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "id": 21624, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "15739:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21622, + "name": "LogFreezeTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20733, + "src": "15712:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$_t_uint256_$returns$__$", + "typeString": "function (bool,uint256)" + } + }, + "id": 21625, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15712:31:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21626, + "nodeType": "EmitStatement", + "src": "15707:36:59" + } + ] + }, + "documentation": "@notice un-freeze all the transfers", + "id": 21628, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21612, + "modifierName": { + "argumentTypes": null, + "id": 21611, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "15638:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "15638:9:59" + } + ], + "name": "unfreezeTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21610, + "nodeType": "ParameterList", + "parameters": [], + "src": "15628:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21613, + "nodeType": "ParameterList", + "parameters": [], + "src": "15648:0:59" + }, + "scope": 22534, + "src": "15602:148:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21637, + "nodeType": "Block", + "src": "15901:72:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21632, + "name": "checkpointTotalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20661, + "src": "15929:21:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 21633, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22864 + ], + "referencedDeclaration": 22864, + "src": "15952:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 21634, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15952:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21631, + "name": "adjustCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21705, + "src": "15911:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$returns$__$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256)" + } + }, + "id": 21635, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15911:55:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21636, + "nodeType": "ExpressionStatement", + "src": "15911:55:59" + } + ] + }, + "documentation": "@notice adjust totalsupply at checkpoint after minting or burning tokens", + "id": 21638, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustTotalSupplyCheckpoints", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21629, + "nodeType": "ParameterList", + "parameters": [], + "src": "15889:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21630, + "nodeType": "ParameterList", + "parameters": [], + "src": "15901:0:59" + }, + "scope": 22534, + "src": "15852:121:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21652, + "nodeType": "Block", + "src": "16198:87:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21644, + "name": "checkpointBalances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20658, + "src": "16226:18:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint storage ref[] storage ref)" + } + }, + "id": 21646, + "indexExpression": { + "argumentTypes": null, + "id": 21645, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21640, + "src": "16245:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "16226:29:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21648, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21640, + "src": "16267:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21647, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "16257:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21649, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16257:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21643, + "name": "adjustCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21705, + "src": "16208:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$returns$__$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256)" + } + }, + "id": 21650, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16208:70:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21651, + "nodeType": "ExpressionStatement", + "src": "16208:70:59" + } + ] + }, + "documentation": "@notice adjust token holder balance at checkpoint after a token transfer\n@param _investor address of the token holder affected", + "id": 21653, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustBalanceCheckpoints", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21641, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21640, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 21653, + "src": "16170:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21639, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "16170:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "16169:19:59" + }, + "payable": false, + "returnParameters": { + "id": 21642, + "nodeType": "ParameterList", + "parameters": [], + "src": "16198:0:59" + }, + "scope": 22534, + "src": "16136:149:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21704, + "nodeType": "Block", + "src": "16582:817:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21663, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21661, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "16629:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21662, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16652:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "16629:24:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21666, + "nodeType": "IfStatement", + "src": "16625:61:59", + "trueBody": { + "id": 21665, + "nodeType": "Block", + "src": "16655:31:59", + "statements": [ + { + "expression": null, + "functionReturnParameters": 21660, + "id": 21664, + "nodeType": "Return", + "src": "16669:7:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21670, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21667, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "16778:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21668, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16778:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21669, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16801:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "16778:24:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21682, + "nodeType": "IfStatement", + "src": "16774:247:59", + "trueBody": { + "id": 21681, + "nodeType": "Block", + "src": "16804:217:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21675, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "16900:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21676, + "name": "_newValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21658, + "src": "16948:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": null, + "id": 21674, + "name": "Checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20653, + "src": "16853:10:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_Checkpoint_$20653_storage_ptr_$", + "typeString": "type(struct SecurityToken.Checkpoint storage pointer)" + } + }, + "id": 21677, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [ + "checkpointId", + "value" + ], + "nodeType": "FunctionCall", + "src": "16853:123:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 21671, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "16818:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21673, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16818:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_struct$_Checkpoint_$20653_storage_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref) returns (uint256)" + } + }, + "id": 21678, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16818:172:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21679, + "nodeType": "ExpressionStatement", + "src": "16818:172:59" + }, + { + "expression": null, + "functionReturnParameters": 21660, + "id": 21680, + "nodeType": "Return", + "src": "17004:7:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21691, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21683, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "17081:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21688, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21687, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21684, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "17094:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21685, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17094:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21686, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17116:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "17094:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "17081:37:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 21689, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "17081:50:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 21690, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "17135:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "17081:73:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21694, + "nodeType": "IfStatement", + "src": "17077:110:59", + "trueBody": { + "id": 21693, + "nodeType": "Block", + "src": "17156:31:59", + "statements": [ + { + "expression": null, + "functionReturnParameters": 21660, + "id": 21692, + "nodeType": "Return", + "src": "17170:7:59" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21699, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "17314:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21700, + "name": "_newValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21658, + "src": "17358:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": null, + "id": 21698, + "name": "Checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20653, + "src": "17271:10:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_Checkpoint_$20653_storage_ptr_$", + "typeString": "type(struct SecurityToken.Checkpoint storage pointer)" + } + }, + "id": 21701, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [ + "checkpointId", + "value" + ], + "nodeType": "FunctionCall", + "src": "17271:111:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 21695, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "17240:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21697, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17240:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_struct$_Checkpoint_$20653_storage_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref) returns (uint256)" + } + }, + "id": 21702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17240:152:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21703, + "nodeType": "ExpressionStatement", + "src": "17240:152:59" + } + ] + }, + "documentation": "@notice store the changes to the checkpoint objects\n@param _checkpoints the affected checkpoint object array\n@param _newValue the new value that needs to be stored", + "id": 21705, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustCheckpoints", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21659, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21656, + "name": "_checkpoints", + "nodeType": "VariableDeclaration", + "scope": 21705, + "src": "16519:33:59", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + }, + "typeName": { + "baseType": { + "contractScope": null, + "id": 21654, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "16519:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 21655, + "length": null, + "nodeType": "ArrayTypeName", + "src": "16519:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21658, + "name": "_newValue", + "nodeType": "VariableDeclaration", + "scope": 21705, + "src": "16554:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21657, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "16554:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "16518:54:59" + }, + "payable": false, + "returnParameters": { + "id": 21660, + "nodeType": "ParameterList", + "parameters": [], + "src": "16582:0:59" + }, + "scope": 22534, + "src": "16492:907:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21750, + "nodeType": "Block", + "src": "17663:296:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21715, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "17693:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21716, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17693:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21717, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17705:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21718, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21709, + "src": "17710:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21714, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "17673:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 21719, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17673:44:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21720, + "nodeType": "ExpressionStatement", + "src": "17673:44:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21723, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "17750:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17750:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21725, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17762:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21726, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21709, + "src": "17767:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21722, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "17735:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 21727, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17735:39:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 21728, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17776:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 21721, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "17727:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21729, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17727:73:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21730, + "nodeType": "ExpressionStatement", + "src": "17727:73:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21732, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "17835:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21733, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17835:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21731, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "17810:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21734, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17810:36:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21735, + "nodeType": "ExpressionStatement", + "src": "17810:36:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21737, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17881:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21736, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "17856:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21738, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17856:29:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21739, + "nodeType": "ExpressionStatement", + "src": "17856:29:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21743, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17918:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21744, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21709, + "src": "17923:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21741, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23374, + "src": "17903:5:59", + "typeDescriptions": { + "typeIdentifier": "t_super$_SecurityToken_$22534", + "typeString": "contract super SecurityToken" + } + }, + "id": 21742, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "transfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 22924, + "src": "17903:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) returns (bool)" + } + }, + "id": 21745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17903:27:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21740, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "17895:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21746, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17895:36:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21747, + "nodeType": "ExpressionStatement", + "src": "17895:36:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21748, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17948:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21713, + "id": 21749, + "nodeType": "Return", + "src": "17941:11:59" + } + ] + }, + "documentation": "@notice Overloaded version of the transfer function\n@param _to receiver of transfer\n@param _value value of transfer\n@return bool success", + "id": 21751, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "transfer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21710, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21707, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21751, + "src": "17604:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21706, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "17604:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21709, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 21751, + "src": "17617:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21708, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "17617:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "17603:29:59" + }, + "payable": false, + "returnParameters": { + "id": 21713, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21712, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 21751, + "src": "17649:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21711, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "17649:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "17648:14:59" + }, + "scope": 22534, + "src": "17586:373:59", + "stateMutability": "nonpayable", + "superFunction": 22924, + "visibility": "public" + }, + { + "body": { + "id": 21796, + "nodeType": "Block", + "src": "18285:292:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21763, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18315:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21764, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18322:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21765, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21757, + "src": "18327:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21762, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "18295:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 21766, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18295:39:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21767, + "nodeType": "ExpressionStatement", + "src": "18295:39:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21770, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18367:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21771, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18374:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21772, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21757, + "src": "18379:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21769, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "18352:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 21773, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18352:34:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 21774, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18388:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 21768, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "18344:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21775, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18344:68:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21776, + "nodeType": "ExpressionStatement", + "src": "18344:68:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21778, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18447:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21777, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "18422:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21779, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18422:31:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21780, + "nodeType": "ExpressionStatement", + "src": "18422:31:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21782, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18488:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21781, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "18463:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21783, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18463:29:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21784, + "nodeType": "ExpressionStatement", + "src": "18463:29:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21788, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18529:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21789, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18536:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21790, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21757, + "src": "18541:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21786, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23374, + "src": "18510:5:59", + "typeDescriptions": { + "typeIdentifier": "t_super$_SecurityToken_$22534", + "typeString": "contract super SecurityToken" + } + }, + "id": 21787, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "transferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 23146, + "src": "18510:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 21791, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18510:38:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21785, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "18502:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21792, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18502:47:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21793, + "nodeType": "ExpressionStatement", + "src": "18502:47:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21794, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18566:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21761, + "id": 21795, + "nodeType": "Return", + "src": "18559:11:59" + } + ] + }, + "documentation": "@notice Overloaded version of the transferFrom function\n@param _from sender of transfer\n@param _to receiver of transfer\n@param _value value of transfer\n@return bool success", + "id": 21797, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "transferFrom", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21758, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21753, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18211:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21752, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18211:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21755, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18226:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21754, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18226:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21757, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18239:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21756, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18239:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18210:44:59" + }, + "payable": false, + "returnParameters": { + "id": 21761, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21760, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18271:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21759, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "18271:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18270:14:59" + }, + "scope": 22534, + "src": "18189:388:59", + "stateMutability": "nonpayable", + "superFunction": 23146, + "visibility": "public" + }, + { + "body": { + "id": 21931, + "nodeType": "Block", + "src": "18978:1097:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 21812, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "18992:7:59", + "subExpression": { + "argumentTypes": null, + "id": 21811, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "18993:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21928, + "nodeType": "IfStatement", + "src": "18988:1061:59", + "trueBody": { + "id": 21927, + "nodeType": "Block", + "src": "19001:1048:59", + "statements": [ + { + "assignments": [ + 21814 + ], + "declarations": [ + { + "constant": false, + "id": 21814, + "name": "isTransfer", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19015:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21813, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19015:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21816, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21815, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19033:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19015:23:59" + }, + { + "condition": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21817, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "19056:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 21822, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21819, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "19081:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21820, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19081:8:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 21818, + "name": "getSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22324, + "src": "19074:6:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_memory_ptr_$returns$_t_bytes4_$", + "typeString": "function (bytes memory) pure returns (bytes4)" + } + }, + "id": 21821, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19074:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19056:35:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21828, + "nodeType": "IfStatement", + "src": "19052:89:59", + "trueBody": { + "id": 21827, + "nodeType": "Block", + "src": "19093:48:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21825, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21823, + "name": "isTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21814, + "src": "19109:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21824, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19122:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19109:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21826, + "nodeType": "ExpressionStatement", + "src": "19109:17:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21834, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21829, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "19158:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21831, + "indexExpression": { + "argumentTypes": null, + "id": 21830, + "name": "TRANSFERMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10022, + "src": "19166:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19158:28:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21832, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19158:35:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21833, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19197:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "19158:40:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21838, + "nodeType": "IfStatement", + "src": "19154:90:59", + "trueBody": { + "id": 21837, + "nodeType": "Block", + "src": "19200:44:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21835, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19225:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21810, + "id": 21836, + "nodeType": "Return", + "src": "19218:11:59" + } + ] + } + }, + { + "assignments": [ + 21840 + ], + "declarations": [ + { + "constant": false, + "id": 21840, + "name": "isInvalid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19257:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21839, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19257:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21842, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21841, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19274:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19257:22:59" + }, + { + "assignments": [ + 21844 + ], + "declarations": [ + { + "constant": false, + "id": 21844, + "name": "isValid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19293:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21843, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19293:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21846, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21845, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19308:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19293:20:59" + }, + { + "assignments": [ + 21848 + ], + "declarations": [ + { + "constant": false, + "id": 21848, + "name": "isForceValid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19327:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21847, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19327:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21850, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21849, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19347:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19327:25:59" + }, + { + "body": { + "id": 21916, + "nodeType": "Block", + "src": "19430:539:59", + "statements": [ + { + "assignments": [ + 21867 + ], + "declarations": [ + { + "constant": false, + "id": 21867, + "name": "valid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19448:29:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "typeName": { + "contractScope": null, + "id": 21866, + "name": "ITransferManager.Result", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 18484, + "src": "19448:23:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21882, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21877, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21799, + "src": "19559:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21878, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21801, + "src": "19566:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21879, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21803, + "src": "19571:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21880, + "name": "isTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21814, + "src": "19580:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21869, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "19497:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21871, + "indexExpression": { + "argumentTypes": null, + "id": 21870, + "name": "TRANSFERMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10022, + "src": "19505:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19497:28:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21873, + "indexExpression": { + "argumentTypes": null, + "id": 21872, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21852, + "src": "19526:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19497:31:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21874, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "19497:45:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21868, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19480:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21875, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19480:63:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITransferManager_$18520", + "typeString": "contract ITransferManager" + } + }, + "id": 21876, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "verifyTransfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 18497, + "src": "19480:78:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bool_$returns$_t_enum$_Result_$18484_$", + "typeString": "function (address,address,uint256,bool) external returns (enum ITransferManager.Result)" + } + }, + "id": 21881, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19480:111:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "19448:143:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "id": 21887, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21883, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21867, + "src": "19613:5:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21884, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19622:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21885, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "Result", + "nodeType": "MemberAccess", + "referencedDeclaration": 18484, + "src": "19622:23:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18484_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 21886, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "INVALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19622:31:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "src": "19613:40:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21893, + "nodeType": "IfStatement", + "src": "19609:103:59", + "trueBody": { + "id": 21892, + "nodeType": "Block", + "src": "19655:57:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21888, + "name": "isInvalid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21840, + "src": "19677:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21889, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19689:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19677:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21891, + "nodeType": "ExpressionStatement", + "src": "19677:16:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "id": 21898, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21894, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21867, + "src": "19733:5:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21895, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19742:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21896, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "Result", + "nodeType": "MemberAccess", + "referencedDeclaration": 18484, + "src": "19742:23:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18484_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 21897, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19742:29:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "src": "19733:38:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21904, + "nodeType": "IfStatement", + "src": "19729:99:59", + "trueBody": { + "id": 21903, + "nodeType": "Block", + "src": "19773:55:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21901, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21899, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21844, + "src": "19795:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21900, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19805:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19795:14:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21902, + "nodeType": "ExpressionStatement", + "src": "19795:14:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "id": 21909, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21905, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21867, + "src": "19849:5:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21906, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19858:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21907, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "Result", + "nodeType": "MemberAccess", + "referencedDeclaration": 18484, + "src": "19858:23:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18484_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 21908, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "FORCE_VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19858:35:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "src": "19849:44:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21915, + "nodeType": "IfStatement", + "src": "19845:110:59", + "trueBody": { + "id": 21914, + "nodeType": "Block", + "src": "19895:60:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21912, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21910, + "name": "isForceValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21848, + "src": "19917:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21911, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19932:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19917:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21913, + "nodeType": "ExpressionStatement", + "src": "19917:19:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21860, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21855, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21852, + "src": "19384:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21856, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "19388:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21858, + "indexExpression": { + "argumentTypes": null, + "id": 21857, + "name": "TRANSFERMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10022, + "src": "19396:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19388:28:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21859, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19388:35:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "19384:39:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21917, + "initializationExpression": { + "assignments": [ + 21852 + ], + "declarations": [ + { + "constant": false, + "id": 21852, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19371:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21851, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "19371:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21854, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 21853, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19381:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19371:11:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 21862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "19425:3:59", + "subExpression": { + "argumentTypes": null, + "id": 21861, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21852, + "src": "19425:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 21863, + "nodeType": "ExpressionStatement", + "src": "19425:3:59" + }, + "nodeType": "ForStatement", + "src": "19366:603:59" + }, + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "id": 21918, + "name": "isForceValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21848, + "src": "19989:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "id": 21920, + "name": "isInvalid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21840, + "src": "20012:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 21922, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21844, + "src": "20032:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21923, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "20012:27:59", + "trueExpression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21921, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20024:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21924, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "20011:29:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21925, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "19989:51:59", + "trueExpression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21919, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20004:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 21810, + "id": 21926, + "nodeType": "Return", + "src": "19982:58:59" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21929, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20063:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 21810, + "id": 21930, + "nodeType": "Return", + "src": "20056:12:59" + } + ] + }, + "documentation": "@notice validate transfer with TransferManager module if it exists\n@dev TransferManager module has a key of 2\n@param _from sender of transfer\n@param _to receiver of transfer\n@param _amount value of transfer\n@return bool", + "id": 21932, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 21806, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21803, + "src": "18954:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 21807, + "modifierName": { + "argumentTypes": null, + "id": 21805, + "name": "checkGranularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20849, + "src": "18937:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "18937:25:59" + } + ], + "name": "verifyTransfer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21804, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21799, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18885:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21798, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18885:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21801, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18900:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21800, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18900:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21803, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18913:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21802, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18913:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18884:45:59" + }, + "payable": false, + "returnParameters": { + "id": 21810, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21809, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18972:4:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21808, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "18972:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18971:6:59" + }, + "scope": 22534, + "src": "18861:1214:59", + "stateMutability": "nonpayable", + "superFunction": 9959, + "visibility": "public" + }, + { + "body": { + "id": 21945, + "nodeType": "Block", + "src": "20208:87:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21939, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21937, + "name": "finishedIssuerMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20664, + "src": "20218:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21938, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20242:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "20218:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21940, + "nodeType": "ExpressionStatement", + "src": "20218:28:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21942, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "20284:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21941, + "name": "LogFinishMintingIssuer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20743, + "src": "20261:22:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256)" + } + }, + "id": 21943, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20261:27:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21944, + "nodeType": "EmitStatement", + "src": "20256:32:59" + } + ] + }, + "documentation": "@notice End token minting period permanently for Issuer", + "id": 21946, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21935, + "modifierName": { + "argumentTypes": null, + "id": 21934, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "20198:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "20198:9:59" + } + ], + "name": "finishMintingIssuer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21933, + "nodeType": "ParameterList", + "parameters": [], + "src": "20188:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21936, + "nodeType": "ParameterList", + "parameters": [], + "src": "20208:0:59" + }, + "scope": 22534, + "src": "20160:135:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21959, + "nodeType": "Block", + "src": "20423:81:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21953, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21951, + "name": "finishedSTOMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20667, + "src": "20433:18:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21952, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20454:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "20433:25:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21954, + "nodeType": "ExpressionStatement", + "src": "20433:25:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21956, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "20493:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21955, + "name": "LogFinishMintingSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20747, + "src": "20473:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256)" + } + }, + "id": 21957, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20473:24:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21958, + "nodeType": "EmitStatement", + "src": "20468:29:59" + } + ] + }, + "documentation": "@notice End token minting period permanently for STOs", + "id": 21960, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21949, + "modifierName": { + "argumentTypes": null, + "id": 21948, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "20413:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "20413:9:59" + } + ], + "name": "finishMintingSTO", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21947, + "nodeType": "ParameterList", + "parameters": [], + "src": "20403:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21950, + "nodeType": "ParameterList", + "parameters": [], + "src": "20423:0:59" + }, + "scope": 22534, + "src": "20378:126:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 22046, + "nodeType": "Block", + "src": "21016:553:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21983, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21979, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21034:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21981, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21055:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21980, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21047:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21982, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21047:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "21034:23:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e766573746f7220616464726573732073686f756c64206e6f74206265203078", + "id": 21984, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21059:35:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_92c9ad5839d9e6c845f0585522dbe71544d58a6d51db03cf580afd2032f01f8c", + "typeString": "literal_string \"Investor address should not be 0x\"" + }, + "value": "Investor address should not be 0x" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_92c9ad5839d9e6c845f0585522dbe71544d58a6d51db03cf580afd2032f01f8c", + "typeString": "literal_string \"Investor address should not be 0x\"" + } + ], + "id": 21978, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "21026:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21985, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21026:69:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21986, + "nodeType": "ExpressionStatement", + "src": "21026:69:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21989, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21133:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21988, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21125:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21990, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21125:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21991, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21137:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21992, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21148:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21987, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "21105:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 21993, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21105:51:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21994, + "nodeType": "ExpressionStatement", + "src": "21105:51:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21998, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21197:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21997, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21189:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21999, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21189:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22000, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21201:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22001, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21212:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21996, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "21174:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 22002, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21174:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 22003, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21222:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 21995, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "21166:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21166:80:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22005, + "nodeType": "ExpressionStatement", + "src": "21166:80:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22007, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21281:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22006, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "21256:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 22008, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21256:35:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22009, + "nodeType": "ExpressionStatement", + "src": "21256:35:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 22010, + "name": "adjustTotalSupplyCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21638, + "src": "21301:28:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 22011, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21301:30:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22012, + "nodeType": "ExpressionStatement", + "src": "21301:30:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22018, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22013, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "21341:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22016, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21373:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 22014, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "21356:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22015, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "21356:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22017, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21356:25:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "21341:40:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22019, + "nodeType": "ExpressionStatement", + "src": "21341:40:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22029, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22020, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "21391:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22022, + "indexExpression": { + "argumentTypes": null, + "id": 22021, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21400:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "21391:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22027, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21437:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22023, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "21413:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22025, + "indexExpression": { + "argumentTypes": null, + "id": 22024, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21422:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21413:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22026, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "21413:23:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22028, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21413:32:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "21391:54:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22030, + "nodeType": "ExpressionStatement", + "src": "21391:54:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22032, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21467:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22033, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21478:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22031, + "name": "Minted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9979, + "src": "21460:6:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 22034, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21460:26:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22035, + "nodeType": "EmitStatement", + "src": "21455:31:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22038, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21518:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22037, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21510:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22039, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21510:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22040, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21522:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22041, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21533:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22036, + "name": "Transfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23045, + "src": "21501:8:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 22042, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21501:40:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22043, + "nodeType": "EmitStatement", + "src": "21496:45:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22044, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21558:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21977, + "id": 22045, + "nodeType": "Return", + "src": "21551:11:59" + } + ] + }, + "documentation": "@notice mints new tokens and assigns them to the target _investor.\n@dev Can only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet)\n@param _investor Address to whom the minted tokens will be dilivered\n@param _amount Number of tokens get minted\n@return success", + "id": 22047, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 21967, + "name": "STO_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10025, + "src": "20933:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21968, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20942:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "id": 21969, + "modifierName": { + "argumentTypes": null, + "id": 21966, + "name": "onlyModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20834, + "src": "20922:10:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint8_$_t_bool_$", + "typeString": "modifier (uint8,bool)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20922:25:59" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 21971, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "20965:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 21972, + "modifierName": { + "argumentTypes": null, + "id": 21970, + "name": "checkGranularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20849, + "src": "20948:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20948:25:59" + }, + { + "arguments": [], + "id": 21974, + "modifierName": { + "argumentTypes": null, + "id": 21973, + "name": "isMintingAllowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20872, + "src": "20974:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "20974:18:59" + } + ], + "name": "mint", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21965, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21962, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 22047, + "src": "20879:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21961, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "20879:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21964, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 22047, + "src": "20898:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21963, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20898:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "20878:36:59" + }, + "payable": false, + "returnParameters": { + "id": 21977, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21976, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 22047, + "src": "21002:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21975, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "21002:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "21001:14:59" + }, + "scope": 22534, + "src": "20865:704:59", + "stateMutability": "nonpayable", + "superFunction": 9968, + "visibility": "public" + }, + { + "body": { + "id": 22095, + "nodeType": "Block", + "src": "22142:238:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22067, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22063, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22050, + "src": "22160:10:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 22064, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22160:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22065, + "name": "_amounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22053, + "src": "22181:8:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 22066, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22181:15:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "22160:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69732d6d6174636820696e20746865206c656e677468206f662074686520617272617973", + "id": 22068, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22198:39:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e6e9985f4f54b573f3a5eba669f45bb98ec50cd60909ea443be6588371310a0e", + "typeString": "literal_string \"Mis-match in the length of the arrays\"" + }, + "value": "Mis-match in the length of the arrays" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e6e9985f4f54b573f3a5eba669f45bb98ec50cd60909ea443be6588371310a0e", + "typeString": "literal_string \"Mis-match in the length of the arrays\"" + } + ], + "id": 22062, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "22152:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22069, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22152:86:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22070, + "nodeType": "ExpressionStatement", + "src": "22152:86:59" + }, + { + "body": { + "id": 22091, + "nodeType": "Block", + "src": "22296:57:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22083, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22050, + "src": "22315:10:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 22085, + "indexExpression": { + "argumentTypes": null, + "id": 22084, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22326:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22315:13:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22086, + "name": "_amounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22053, + "src": "22330:8:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 22088, + "indexExpression": { + "argumentTypes": null, + "id": 22087, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22339:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22330:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22082, + "name": "mint", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22047 + ], + "referencedDeclaration": 22047, + "src": "22310:4:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) returns (bool)" + } + }, + "id": 22089, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22310:32:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22090, + "nodeType": "ExpressionStatement", + "src": "22310:32:59" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22078, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22075, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22268:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22076, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22050, + "src": "22272:10:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 22077, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22272:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "22268:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22092, + "initializationExpression": { + "assignments": [ + 22072 + ], + "declarations": [ + { + "constant": false, + "id": 22072, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22253:9:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22071, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "22253:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22074, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22073, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22265:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "22253:13:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 22080, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "22291:3:59", + "subExpression": { + "argumentTypes": null, + "id": 22079, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22291:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22081, + "nodeType": "ExpressionStatement", + "src": "22291:3:59" + }, + "nodeType": "ForStatement", + "src": "22248:105:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22093, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22369:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 22061, + "id": 22094, + "nodeType": "Return", + "src": "22362:11:59" + } + ] + }, + "documentation": "@notice mints new tokens and assigns them to the target _investor.\nCan only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet)\n@param _investors A list of addresses to whom the minted tokens will be dilivered\n@param _amounts A list of number of tokens get minted and transfer to corresponding address of the investor from _investor[] list\n@return success", + "id": 22096, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 22056, + "name": "STO_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10025, + "src": "22104:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22057, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22113:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "id": 22058, + "modifierName": { + "argumentTypes": null, + "id": 22055, + "name": "onlyModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20834, + "src": "22093:10:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint8_$_t_bool_$", + "typeString": "modifier (uint8,bool)" + } + }, + "nodeType": "ModifierInvocation", + "src": "22093:25:59" + } + ], + "name": "mintMulti", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22054, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22050, + "name": "_investors", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22044:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 22048, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22044:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 22049, + "length": null, + "nodeType": "ArrayTypeName", + "src": "22044:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22053, + "name": "_amounts", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22066:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 22051, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "22066:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22052, + "length": null, + "nodeType": "ArrayTypeName", + "src": "22066:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22043:42:59" + }, + "payable": false, + "returnParameters": { + "id": 22061, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22060, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22128:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 22059, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "22128:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22127:14:59" + }, + "scope": 22534, + "src": "22025:355:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 22149, + "nodeType": "Block", + "src": "22966:361:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22112, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22107, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "22980:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 22109, + "indexExpression": { + "argumentTypes": null, + "id": 22108, + "name": "PERMISSIONMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10019, + "src": "22988:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22980:30:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 22110, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22980:37:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22111, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23021:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "22980:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22116, + "nodeType": "IfStatement", + "src": "22976:85:59", + "trueBody": { + "id": 22115, + "nodeType": "Block", + "src": "23024:37:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 22113, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23045:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 22106, + "id": 22114, + "nodeType": "Return", + "src": "23038:12:59" + } + ] + } + }, + { + "body": { + "id": 22147, + "nodeType": "Block", + "src": "23137:184:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22139, + "name": "_delegate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22098, + "src": "23239:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22140, + "name": "_module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22100, + "src": "23250:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22141, + "name": "_perm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22102, + "src": "23259:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22131, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "23174:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 22133, + "indexExpression": { + "argumentTypes": null, + "id": 22132, + "name": "PERMISSIONMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10019, + "src": "23182:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23174:30:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 22135, + "indexExpression": { + "argumentTypes": null, + "id": 22134, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22118, + "src": "23205:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23174:33:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 22136, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "23174:47:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22130, + "name": "IPermissionManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 13247, + "src": "23155:18:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IPermissionManager_$13247_$", + "typeString": "type(contract IPermissionManager)" + } + }, + "id": 22137, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23155:67:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IPermissionManager_$13247", + "typeString": "contract IPermissionManager" + } + }, + "id": 22138, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "checkPermission", + "nodeType": "MemberAccess", + "referencedDeclaration": 13226, + "src": "23155:83:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_address_$_t_address_$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (address,address,bytes32) view external returns (bool)" + } + }, + "id": 22142, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23155:110:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22146, + "nodeType": "IfStatement", + "src": "23151:160:59", + "trueBody": { + "id": 22145, + "nodeType": "Block", + "src": "23267:44:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22143, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23292:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 22106, + "id": 22144, + "nodeType": "Return", + "src": "23285:11:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22126, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22121, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22118, + "src": "23089:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22122, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "23093:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 22124, + "indexExpression": { + "argumentTypes": null, + "id": 22123, + "name": "PERMISSIONMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10019, + "src": "23101:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23093:30:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 22125, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "23093:37:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "23089:41:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22148, + "initializationExpression": { + "assignments": [ + 22118 + ], + "declarations": [ + { + "constant": false, + "id": 22118, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "23076:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 22117, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "23076:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22120, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22119, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23086:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "23076:11:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 22128, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "23132:3:59", + "subExpression": { + "argumentTypes": null, + "id": 22127, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22118, + "src": "23132:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 22129, + "nodeType": "ExpressionStatement", + "src": "23132:3:59" + }, + "nodeType": "ForStatement", + "src": "23071:250:59" + } + ] + }, + "documentation": "@notice Validate permissions with PermissionManager if it exists, If no Permission return false\n@dev Note that IModule withPerm will allow ST owner all permissions anyway\n@dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions)\n@param _delegate address of delegate\n@param _module address of PermissionManager module\n@param _perm the permissions\n@return success", + "id": 22150, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "checkPermission", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22103, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22098, + "name": "_delegate", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22889:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22097, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22889:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22100, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22908:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22099, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22908:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22102, + "name": "_perm", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22925:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 22101, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "22925:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22888:51:59" + }, + "payable": false, + "returnParameters": { + "id": 22106, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22105, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22960:4:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 22104, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "22960:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22959:6:59" + }, + "scope": 22534, + "src": "22864:463:59", + "stateMutability": "view", + "superFunction": 10048, + "visibility": "public" + }, + { + "body": { + "id": 22163, + "nodeType": "Block", + "src": "23560:57:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22161, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22157, + "name": "tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20640, + "src": "23570:11:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22159, + "name": "_tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22152, + "src": "23597:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22158, + "name": "ITokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10218, + "src": "23584:12:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITokenBurner_$10218_$", + "typeString": "type(contract ITokenBurner)" + } + }, + "id": 22160, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23584:26:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "src": "23570:40:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "id": 22162, + "nodeType": "ExpressionStatement", + "src": "23570:40:59" + } + ] + }, + "documentation": "@notice used to set the token Burner address. It only be called by the owner\n@param _tokenBurner Address of the token burner contract", + "id": 22164, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 22155, + "modifierName": { + "argumentTypes": null, + "id": 22154, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "23550:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "23550:9:59" + } + ], + "name": "setTokenBurner", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22153, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22152, + "name": "_tokenBurner", + "nodeType": "VariableDeclaration", + "scope": 22164, + "src": "23521:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22151, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23521:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23520:22:59" + }, + "payable": false, + "returnParameters": { + "id": 22156, + "nodeType": "ParameterList", + "parameters": [], + "src": "23560:0:59" + }, + "scope": 22534, + "src": "23497:120:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 22265, + "nodeType": "Block", + "src": "23811:931:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22173, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "23841:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22174, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "23841:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22176, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23861:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22175, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "23853:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22177, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23853:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22178, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "23865:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22172, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "23821:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 22179, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23821:51:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22180, + "nodeType": "ExpressionStatement", + "src": "23821:51:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 22186, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22182, + "name": "tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20640, + "src": "23890:11:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22184, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23913:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22183, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "23905:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22185, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23905:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "23890:25:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "546f6b656e204275726e657220636f6e74726163742061646472657373206973206e6f742073657420796574", + "id": 22187, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23917:46:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b1e20e36cf137ffa348b540450b55b5e970f06fe4fc7c40c3990ff61e4871e2f", + "typeString": "literal_string \"Token Burner contract address is not set yet\"" + }, + "value": "Token Burner contract address is not set yet" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b1e20e36cf137ffa348b540450b55b5e970f06fe4fc7c40c3990ff61e4871e2f", + "typeString": "literal_string \"Token Burner contract address is not set yet\"" + } + ], + "id": 22181, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "23882:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22188, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23882:82:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22189, + "nodeType": "ExpressionStatement", + "src": "23882:82:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22192, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "23997:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22193, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "23997:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22195, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24017:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22194, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24009:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22196, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24009:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22197, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24021:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22191, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "23982:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 22198, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23982:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 22199, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24030:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 22190, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "23974:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22200, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23974:80:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22201, + "nodeType": "ExpressionStatement", + "src": "23974:80:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22208, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22203, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24072:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22204, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "24082:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22207, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22205, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24091:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22206, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24091:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24082:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "24072:30:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "56616c75652073686f756c64206e6f2062652067726561746572207468616e207468652062616c616e6365206f66206d73672e73656e646572", + "id": 22209, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24104:59:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b61a8271ddd9a6e3d197611651578d62cfc7171b9d88bf350a7c0ea036caf1ea", + "typeString": "literal_string \"Value should no be greater than the balance of msg.sender\"" + }, + "value": "Value should no be greater than the balance of msg.sender" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b61a8271ddd9a6e3d197611651578d62cfc7171b9d88bf350a7c0ea036caf1ea", + "typeString": "literal_string \"Value should no be greater than the balance of msg.sender\"" + } + ], + "id": 22202, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "24064:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22210, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24064:100:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22211, + "nodeType": "ExpressionStatement", + "src": "24064:100:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22213, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24199:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22214, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24199:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22212, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "24174:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 22215, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24174:36:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22216, + "nodeType": "ExpressionStatement", + "src": "24174:36:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 22217, + "name": "adjustTotalSupplyCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21638, + "src": "24220:28:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 22218, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24220:30:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22219, + "nodeType": "ExpressionStatement", + "src": "24220:30:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22231, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22220, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "24440:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22223, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22221, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24449:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22222, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24449:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "24440:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22229, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24488:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22224, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "24463:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22227, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22225, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24472:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22226, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24472:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24463:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22228, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "24463:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22230, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24463:32:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "24440:55:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22232, + "nodeType": "ExpressionStatement", + "src": "24440:55:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22236, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24530:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22237, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24530:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22238, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24542:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 22234, + "name": "tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20640, + "src": "24513:11:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "id": 22235, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "burn", + "nodeType": "MemberAccess", + "referencedDeclaration": 10217, + "src": "24513:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 22239, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24513:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "546f6b656e206275726e65722070726f63657373206973206e6f742076616c696461746564", + "id": 22240, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24551:39:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5ccda958cac3717658218d89784f10f8d0a910ee0bbde8a05008990ae73f253b", + "typeString": "literal_string \"Token burner process is not validated\"" + }, + "value": "Token burner process is not validated" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5ccda958cac3717658218d89784f10f8d0a910ee0bbde8a05008990ae73f253b", + "typeString": "literal_string \"Token burner process is not validated\"" + } + ], + "id": 22233, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "24505:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22241, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24505:86:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22242, + "nodeType": "ExpressionStatement", + "src": "24505:86:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22248, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22243, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "24601:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22246, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24633:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 22244, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "24616:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22245, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "24616:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22247, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24616:24:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "24601:39:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22249, + "nodeType": "ExpressionStatement", + "src": "24601:39:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22251, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24661:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22252, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24661:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22253, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24673:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22250, + "name": "Burnt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9985, + "src": "24655:5:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 22254, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24655:25:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22255, + "nodeType": "EmitStatement", + "src": "24650:30:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22257, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24704:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22258, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24704:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22260, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24724:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22259, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24716:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22261, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24716:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22262, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24728:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22256, + "name": "Transfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23045, + "src": "24695:8:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 22263, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24695:40:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22264, + "nodeType": "EmitStatement", + "src": "24690:45:59" + } + ] + }, + "documentation": "@notice Burn function used to burn the securityToken\n@param _value No. of token that get burned", + "id": 22266, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 22169, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "23796:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22170, + "modifierName": { + "argumentTypes": null, + "id": 22168, + "name": "checkGranularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20849, + "src": "23779:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "23779:24:59" + } + ], + "name": "burn", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22167, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22166, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 22266, + "src": "23763:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22165, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "23763:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23762:16:59" + }, + "payable": false, + "returnParameters": { + "id": 22171, + "nodeType": "ParameterList", + "parameters": [], + "src": "23811:0:59" + }, + "scope": 22534, + "src": "23749:993:59", + "stateMutability": "nonpayable", + "superFunction": 9973, + "visibility": "public" + }, + { + "body": { + "id": 22323, + "nodeType": "Block", + "src": "24935:197:59", + "statements": [ + { + "assignments": [ + 22274 + ], + "declarations": [ + { + "constant": false, + "id": 22274, + "name": "len", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "24945:8:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22273, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "24945:4:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22283, + "initialValue": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22278, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22275, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22268, + "src": "24956:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 22276, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24956:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "hexValue": "34", + "id": 22277, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24971:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "24956:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "hexValue": "34", + "id": 22281, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24990:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "id": 22282, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "24956:35:59", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22279, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22268, + "src": "24975:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 22280, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24975:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "24945:46:59" + }, + { + "body": { + "id": 22321, + "nodeType": "Block", + "src": "25032:94:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22319, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22294, + "name": "sig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22271, + "src": "25046:3:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22317, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22297, + "name": "sig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22271, + "src": "25064:3:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "id": 22296, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25059:4:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": "uint" + }, + "id": 22298, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25059:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22316, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22300, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22268, + "src": "25076:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 22302, + "indexExpression": { + "argumentTypes": null, + "id": 22301, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25082:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25076:8:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + ], + "id": 22299, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25071:4:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": "uint" + }, + "id": 22303, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25071:14:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22314, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "hexValue": "32", + "id": 22304, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25089:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22312, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "hexValue": "38", + "id": 22305, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25095:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22310, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22308, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22306, + "name": "len", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22274, + "src": "25100:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22307, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25106:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "25100:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "id": 22309, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25110:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25100:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22311, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "25099:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25095:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22313, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "25094:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25089:24:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22315, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "25088:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25071:43:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25059:55:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22295, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25052:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 22318, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25052:63:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "25046:69:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "id": 22320, + "nodeType": "ExpressionStatement", + "src": "25046:69:59" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22290, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22288, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25018:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 22289, + "name": "len", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22274, + "src": "25022:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25018:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22322, + "initializationExpression": { + "assignments": [ + 22285 + ], + "declarations": [ + { + "constant": false, + "id": 22285, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "25006:6:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22284, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "25006:4:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22287, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22286, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25015:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "25006:10:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 22292, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "25027:3:59", + "subExpression": { + "argumentTypes": null, + "id": 22291, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25027:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22293, + "nodeType": "ExpressionStatement", + "src": "25027:3:59" + }, + "nodeType": "ForStatement", + "src": "25001:125:59" + } + ] + }, + "documentation": "@notice Get function signature from _data\n@param _data passed data\n@return bytes4 sig", + "id": 22324, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getSig", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22269, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22268, + "name": "_data", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "24887:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 22267, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "24887:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24886:13:59" + }, + "payable": false, + "returnParameters": { + "id": 22272, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22271, + "name": "sig", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "24923:10:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 22270, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "24923:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24922:12:59" + }, + "scope": 22534, + "src": "24871:261:59", + "stateMutability": "pure", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 22356, + "nodeType": "Block", + "src": "25357:210:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22340, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22334, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25375:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9935" + }, + "id": 22339, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639936_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9936" + }, + "id": 22337, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "hexValue": "32", + "id": 22335, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25397:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": { + "argumentTypes": null, + "hexValue": "323536", + "id": 22336, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25400:3:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_256_by_1", + "typeString": "int_const 256" + }, + "value": "256" + }, + "src": "25397:6:59", + "typeDescriptions": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639936_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9936" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22338, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25406:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "25397:10:59", + "typeDescriptions": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9935" + } + }, + "src": "25375:32:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 22333, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "25367:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 22341, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25367:41:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22342, + "nodeType": "ExpressionStatement", + "src": "25367:41:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22347, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22343, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25418:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22346, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22344, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25440:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22345, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25462:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "25440:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25418:45:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22348, + "nodeType": "ExpressionStatement", + "src": "25418:45:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22350, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25499:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 22351, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "25520:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22349, + "name": "LogCheckpointCreated", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20739, + "src": "25478:20:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 22352, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25478:46:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22353, + "nodeType": "EmitStatement", + "src": "25473:51:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22354, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25541:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22332, + "id": 22355, + "nodeType": "Return", + "src": "25534:26:59" + } + ] + }, + "documentation": "@notice Creates a checkpoint that can be used to query historical balances / totalSuppy\n@return uint256", + "id": 22357, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 22327, + "name": "CHECKPOINT_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10028, + "src": "25318:14:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22328, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25334:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "id": 22329, + "modifierName": { + "argumentTypes": null, + "id": 22326, + "name": "onlyModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20834, + "src": "25307:10:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint8_$_t_bool_$", + "typeString": "modifier (uint8,bool)" + } + }, + "nodeType": "ModifierInvocation", + "src": "25307:32:59" + } + ], + "name": "createCheckpoint", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22325, + "nodeType": "ParameterList", + "parameters": [], + "src": "25297:2:59" + }, + "payable": false, + "returnParameters": { + "id": 22332, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22331, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22357, + "src": "25348:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22330, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25348:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25347:9:59" + }, + "scope": 22534, + "src": "25272:295:59", + "stateMutability": "nonpayable", + "superFunction": 10091, + "visibility": "public" + }, + { + "body": { + "id": 22371, + "nodeType": "Block", + "src": "25800:87:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22365, + "name": "checkpointTotalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20661, + "src": "25828:21:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "id": 22366, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22359, + "src": "25851:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 22367, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22864 + ], + "referencedDeclaration": 22864, + "src": "25866:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 22368, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25866:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22364, + "name": "getValueAt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22513, + "src": "25817:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256,uint256) view returns (uint256)" + } + }, + "id": 22369, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25817:63:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22363, + "id": 22370, + "nodeType": "Return", + "src": "25810:70:59" + } + ] + }, + "documentation": "@notice Queries totalSupply as of a defined checkpoint\n@param _checkpointId Checkpoint ID to query\n@return uint256", + "id": 22372, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "totalSupplyAt", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22360, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22359, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 22372, + "src": "25748:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22358, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25748:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25747:23:59" + }, + "payable": false, + "returnParameters": { + "id": 22363, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22362, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22372, + "src": "25791:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22361, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25791:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25790:9:59" + }, + "scope": 22534, + "src": "25725:162:59", + "stateMutability": "view", + "superFunction": 10077, + "visibility": "public" + }, + { + "body": { + "id": 22512, + "nodeType": "Block", + "src": "26280:1167:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22387, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22385, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26298:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 22386, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "26315:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26298:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 22384, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "26290:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 22388, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26290:45:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22389, + "nodeType": "ExpressionStatement", + "src": "26290:45:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22392, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22390, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26440:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22391, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26457:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "26440:18:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22396, + "nodeType": "IfStatement", + "src": "26436:55:59", + "trueBody": { + "id": 22395, + "nodeType": "Block", + "src": "26460:31:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22393, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26479:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "functionReturnParameters": 22383, + "id": 22394, + "nodeType": "Return", + "src": "26472:8:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22397, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26504:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22398, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26504:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22399, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26526:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "26504:23:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22404, + "nodeType": "IfStatement", + "src": "26500:74:59", + "trueBody": { + "id": 22403, + "nodeType": "Block", + "src": "26529:45:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22401, + "name": "_currentValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22379, + "src": "26550:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22402, + "nodeType": "Return", + "src": "26543:20:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22410, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22405, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26587:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22407, + "indexExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22406, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26599:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26587:14:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22408, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "26587:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 22409, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26618:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26587:44:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22417, + "nodeType": "IfStatement", + "src": "26583:102:59", + "trueBody": { + "id": 22416, + "nodeType": "Block", + "src": "26633:52:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22411, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26654:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22413, + "indexExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22412, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26666:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26654:14:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22414, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 20652, + "src": "26654:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22415, + "nodeType": "Return", + "src": "26647:27:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22426, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22418, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26698:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22423, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22422, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22419, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26710:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22420, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26710:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22421, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26731:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "26710:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26698:35:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22424, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "26698:48:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 22425, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26749:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26698:64:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22430, + "nodeType": "IfStatement", + "src": "26694:115:59", + "trueBody": { + "id": 22429, + "nodeType": "Block", + "src": "26764:45:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22427, + "name": "_currentValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22379, + "src": "26785:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22428, + "nodeType": "Return", + "src": "26778:20:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22439, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22431, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26822:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22436, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22435, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22432, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26834:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22433, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26834:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22434, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26855:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "26834:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26822:35:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22437, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "26822:48:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 22438, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26874:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26822:65:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22449, + "nodeType": "IfStatement", + "src": "26818:144:59", + "trueBody": { + "id": 22448, + "nodeType": "Block", + "src": "26889:73:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22440, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26910:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22445, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22444, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22441, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26922:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22442, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26922:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22443, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26943:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "26922:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26910:35:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22446, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 20652, + "src": "26910:41:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22447, + "nodeType": "Return", + "src": "26903:48:59" + } + ] + } + }, + { + "assignments": [ + 22451 + ], + "declarations": [ + { + "constant": false, + "id": 22451, + "name": "min", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26971:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22450, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26971:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22453, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22452, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26985:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "26971:15:59" + }, + { + "assignments": [ + 22455 + ], + "declarations": [ + { + "constant": false, + "id": 22455, + "name": "max", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26996:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22454, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26996:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22460, + "initialValue": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22459, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22456, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27010:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22457, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "27010:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22458, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27031:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "27010:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "26996:36:59" + }, + { + "body": { + "id": 22505, + "nodeType": "Block", + "src": "27060:342:59", + "statements": [ + { + "assignments": [ + 22465 + ], + "declarations": [ + { + "constant": false, + "id": 22465, + "name": "mid", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "27074:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22464, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27074:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22472, + "initialValue": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22471, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22468, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22466, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27089:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "id": 22467, + "name": "min", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22451, + "src": "27095:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27089:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22469, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "27088:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": { + "argumentTypes": null, + "hexValue": "32", + "id": 22470, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27102:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "27088:15:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "27074:29:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22478, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22473, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27121:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22475, + "indexExpression": { + "argumentTypes": null, + "id": 22474, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27133:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27121:16:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22476, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "27121:29:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 22477, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "27154:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27121:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22485, + "nodeType": "IfStatement", + "src": "27117:117:59", + "trueBody": { + "id": 22484, + "nodeType": "Block", + "src": "27169:65:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22481, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22479, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27187:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 22480, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27193:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27187:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22482, + "nodeType": "ExpressionStatement", + "src": "27187:9:59" + }, + { + "id": 22483, + "nodeType": "Break", + "src": "27214:5:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22491, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22486, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27251:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22488, + "indexExpression": { + "argumentTypes": null, + "id": 22487, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27263:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27251:16:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22489, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "27251:29:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 22490, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "27283:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27251:45:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 22503, + "nodeType": "Block", + "src": "27350:42:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22501, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22499, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27368:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 22500, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27374:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27368:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22502, + "nodeType": "ExpressionStatement", + "src": "27368:9:59" + } + ] + }, + "id": 22504, + "nodeType": "IfStatement", + "src": "27247:145:59", + "trueBody": { + "id": 22498, + "nodeType": "Block", + "src": "27298:46:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22496, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22492, + "name": "min", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22451, + "src": "27316:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22495, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22493, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27322:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22494, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27328:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "27322:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27316:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22497, + "nodeType": "ExpressionStatement", + "src": "27316:13:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22463, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22461, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27049:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "id": 22462, + "name": "min", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22451, + "src": "27055:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27049:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22506, + "nodeType": "WhileStatement", + "src": "27042:360:59" + }, + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22507, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27418:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22509, + "indexExpression": { + "argumentTypes": null, + "id": 22508, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27430:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27418:16:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22510, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 20652, + "src": "27418:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22511, + "nodeType": "Return", + "src": "27411:29:59" + } + ] + }, + "documentation": "@notice Queries value at a defined checkpoint\n@param checkpoints is array of Checkpoint objects\n@param _checkpointId Checkpoint ID to query\n@param _currentValue Current value of checkpoint\n@return uint256", + "id": 22513, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getValueAt", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22380, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22375, + "name": "checkpoints", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26169:32:59", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + }, + "typeName": { + "baseType": { + "contractScope": null, + "id": 22373, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "26169:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 22374, + "length": null, + "nodeType": "ArrayTypeName", + "src": "26169:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22377, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26203:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22376, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26203:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22379, + "name": "_currentValue", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26226:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22378, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26226:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26168:80:59" + }, + "payable": false, + "returnParameters": { + "id": 22383, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22382, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26271:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22381, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26271:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26270:9:59" + }, + "scope": 22534, + "src": "26149:1298:59", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 22532, + "nodeType": "Block", + "src": "27731:102:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22523, + "name": "checkpointBalances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20658, + "src": "27759:18:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint storage ref[] storage ref)" + } + }, + "id": 22525, + "indexExpression": { + "argumentTypes": null, + "id": 22524, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22515, + "src": "27778:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27759:29:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "id": 22526, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22517, + "src": "27790:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22528, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22515, + "src": "27815:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22527, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "27805:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 22529, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "27805:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22522, + "name": "getValueAt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22513, + "src": "27748:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256,uint256) view returns (uint256)" + } + }, + "id": 22530, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "27748:78:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22521, + "id": 22531, + "nodeType": "Return", + "src": "27741:85:59" + } + ] + }, + "documentation": "@notice Queries balances as of a defined checkpoint\n@param _investor Investor to query balance for\n@param _checkpointId Checkpoint ID to query as of", + "id": 22533, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "balanceOfAt", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22518, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22515, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 22533, + "src": "27660:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22514, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "27660:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22517, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 22533, + "src": "27679:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22516, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27679:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "27659:42:59" + }, + "payable": false, + "returnParameters": { + "id": 22521, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22520, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22533, + "src": "27722:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22519, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27722:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "27721:9:59" + }, + "scope": 22534, + "src": "27639:194:59", + "stateMutability": "view", + "superFunction": 10086, + "visibility": "public" + } + ], + "scope": 22535, + "src": "928:26908:59" + } + ], + "src": "0:27837:59" + }, + "legacyAST": { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/tokens/SecurityToken.sol", + "exportedSymbols": { + "SecurityToken": [ + 22534 + ] + }, + "id": 22535, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 20614, + "literals": [ + "solidity", + "^", + "0.4", + ".24" + ], + "nodeType": "PragmaDirective", + "src": "0:24:59" + }, + { + "absolutePath": "openzeppelin-solidity/contracts/math/Math.sol", + "file": "openzeppelin-solidity/contracts/math/Math.sol", + "id": 20615, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 22662, + "src": "26:55:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IERC20.sol", + "file": "../interfaces/IERC20.sol", + "id": 20616, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9493, + "src": "82:34:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/ISecurityToken.sol", + "file": "../interfaces/ISecurityToken.sol", + "id": 20617, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 10098, + "src": "117:42:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IModule.sol", + "file": "../interfaces/IModule.sol", + "id": 20618, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9656, + "src": "160:35:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IModuleFactory.sol", + "file": "../interfaces/IModuleFactory.sol", + "id": 20619, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9893, + "src": "196:42:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IModuleRegistry.sol", + "file": "../interfaces/IModuleRegistry.sol", + "id": 20620, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9916, + "src": "239:43:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/IST20.sol", + "file": "../interfaces/IST20.sol", + "id": 20621, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 9987, + "src": "283:33:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/TransferManager/ITransferManager.sol", + "file": "../modules/TransferManager/ITransferManager.sol", + "id": 20622, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 18521, + "src": "317:57:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/modules/PermissionManager/IPermissionManager.sol", + "file": "../modules/PermissionManager/IPermissionManager.sol", + "id": 20623, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 13248, + "src": "375:61:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/interfaces/ITokenBurner.sol", + "file": "../interfaces/ITokenBurner.sol", + "id": 20624, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 10219, + "src": "437:40:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "/Users/victorvicente/Repos/Polymath/polymath-core/contracts/RegistryUpdater.sol", + "file": "../RegistryUpdater.sol", + "id": 20625, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 677, + "src": "478:32:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "openzeppelin-solidity/contracts/ReentrancyGuard.sol", + "file": "openzeppelin-solidity/contracts/ReentrancyGuard.sol", + "id": 20626, + "nodeType": "ImportDirective", + "scope": 22535, + "sourceUnit": 22591, + "src": "511:61:59", + "symbolAliases": [], + "unitAlias": "" + }, + { + "baseContracts": [ + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 20627, + "name": "ISecurityToken", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 10097, + "src": "954:14:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ISecurityToken_$10097", + "typeString": "contract ISecurityToken" + } + }, + "id": 20628, + "nodeType": "InheritanceSpecifier", + "src": "954:14:59" + }, + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 20629, + "name": "ReentrancyGuard", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 22590, + "src": "970:15:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ReentrancyGuard_$22590", + "typeString": "contract ReentrancyGuard" + } + }, + "id": 20630, + "nodeType": "InheritanceSpecifier", + "src": "970:15:59" + }, + { + "arguments": null, + "baseName": { + "contractScope": null, + "id": 20631, + "name": "RegistryUpdater", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 676, + "src": "987:15:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_RegistryUpdater_$676", + "typeString": "contract RegistryUpdater" + } + }, + "id": 20632, + "nodeType": "InheritanceSpecifier", + "src": "987:15:59" + } + ], + "contractDependencies": [ + 676, + 9986, + 10097, + 22590, + 22841, + 22937, + 22971, + 23014, + 23046, + 23293 + ], + "contractKind": "contract", + "documentation": "@title Security Token contract\n@notice SecurityToken is an ERC20 token with added capabilities:\n@notice - Implements the ST-20 Interface\n@notice - Transfers are restricted\n@notice - Modules can be attached to it to control its behaviour\n@notice - ST should not be deployed directly, but rather the SecurityTokenRegistry should be used", + "fullyImplemented": true, + "id": 22534, + "linearizedBaseContracts": [ + 22534, + 676, + 22590, + 10097, + 22841, + 9986, + 22971, + 23293, + 22937, + 23014, + 23046 + ], + "name": "SecurityToken", + "nodeType": "ContractDefinition", + "nodes": [ + { + "id": 20635, + "libraryName": { + "contractScope": null, + "id": 20633, + "name": "SafeMath", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 22755, + "src": "1015:8:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SafeMath_$22755", + "typeString": "library SafeMath" + } + }, + "nodeType": "UsingForDirective", + "src": "1009:27:59", + "typeName": { + "id": 20634, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1028:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "constant": true, + "id": 20638, + "name": "securityTokenVersion", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1042:54:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 20636, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1042:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "302e302e31", + "id": 20637, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1089:7:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_ae209a0b48f21c054280f2455d32cf309387644879d9acbd8ffc199163811885", + "typeString": "literal_string \"0.0.1\"" + }, + "value": "0.0.1" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20640, + "name": "tokenBurner", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1145:31:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + }, + "typeName": { + "contractScope": null, + "id": 20639, + "name": "ITokenBurner", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 10218, + "src": "1145:12:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 20643, + "name": "freeze", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1223:26:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20641, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1223:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20642, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1244:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "canonicalName": "SecurityToken.ModuleData", + "id": 20648, + "members": [ + { + "constant": false, + "id": 20645, + "name": "name", + "nodeType": "VariableDeclaration", + "scope": 20648, + "src": "1284:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 20644, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1284:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20647, + "name": "moduleAddress", + "nodeType": "VariableDeclaration", + "scope": 20648, + "src": "1306:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20646, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1306:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "ModuleData", + "nodeType": "StructDefinition", + "scope": 22534, + "src": "1256:78:59", + "visibility": "public" + }, + { + "canonicalName": "SecurityToken.Checkpoint", + "id": 20653, + "members": [ + { + "constant": false, + "id": 20650, + "name": "checkpointId", + "nodeType": "VariableDeclaration", + "scope": 20653, + "src": "1449:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20649, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1449:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20652, + "name": "value", + "nodeType": "VariableDeclaration", + "scope": 20653, + "src": "1479:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20651, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1479:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "Checkpoint", + "nodeType": "StructDefinition", + "scope": 22534, + "src": "1421:78:59", + "visibility": "public" + }, + { + "constant": false, + "id": 20658, + "name": "checkpointBalances", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1505:59:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint[])" + }, + "typeName": { + "id": 20657, + "keyType": { + "id": 20654, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1514:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "1505:33:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint[])" + }, + "valueType": { + "baseType": { + "contractScope": null, + "id": 20655, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "1525:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 20656, + "length": null, + "nodeType": "ArrayTypeName", + "src": "1525:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 20661, + "name": "checkpointTotalSupply", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1570:41:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint[]" + }, + "typeName": { + "baseType": { + "contractScope": null, + "id": 20659, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "1570:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 20660, + "length": null, + "nodeType": "ArrayTypeName", + "src": "1570:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 20664, + "name": "finishedIssuerMinting", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1618:41:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20662, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1618:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20663, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1654:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20667, + "name": "finishedSTOMinting", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1665:38:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20665, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1665:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20666, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1698:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20671, + "name": "transferFunctions", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1710:42:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + }, + "typeName": { + "id": 20670, + "keyType": { + "id": 20668, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "1719:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "Mapping", + "src": "1710:24:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + }, + "valueType": { + "id": 20669, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1729:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20676, + "name": "modules", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1804:46:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData[])" + }, + "typeName": { + "id": 20675, + "keyType": { + "id": 20672, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "1813:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "Mapping", + "src": "1804:31:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData[])" + }, + "valueType": { + "baseType": { + "contractScope": null, + "id": 20673, + "name": "ModuleData", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20648, + "src": "1822:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage_ptr", + "typeString": "struct SecurityToken.ModuleData" + } + }, + "id": 20674, + "length": null, + "nodeType": "ArrayTypeName", + "src": "1822:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.ModuleData[]" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": true, + "id": 20679, + "name": "MAX_MODULES", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1857:38:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20677, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "1857:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": { + "argumentTypes": null, + "hexValue": "3230", + "id": 20678, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1893:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_20_by_1", + "typeString": "int_const 20" + }, + "value": "20" + }, + "visibility": "public" + }, + { + "constant": false, + "id": 20683, + "name": "investorListed", + "nodeType": "VariableDeclaration", + "scope": 22534, + "src": "1902:47:59", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + }, + "typeName": { + "id": 20682, + "keyType": { + "id": 20680, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1911:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "1902:25:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + }, + "valueType": { + "id": 20681, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1922:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "anonymous": false, + "documentation": null, + "id": 20699, + "name": "LogModuleAdded", + "nodeType": "EventDefinition", + "parameters": { + "id": 20698, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20685, + "indexed": true, + "name": "_type", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2032:19:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20684, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "2032:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20687, + "indexed": false, + "name": "_name", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2061:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 20686, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2061:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20689, + "indexed": false, + "name": "_moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2084:22:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20688, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2084:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20691, + "indexed": false, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2116:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20690, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2116:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20693, + "indexed": false, + "name": "_moduleCost", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2141:19:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20692, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2141:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20695, + "indexed": false, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2170:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20694, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2170:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20697, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20699, + "src": "2195:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20696, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2195:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2022:197:59" + }, + "src": "2002:218:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20705, + "name": "LogUpdateTokenDetails", + "nodeType": "EventDefinition", + "parameters": { + "id": 20704, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20701, + "indexed": false, + "name": "_oldDetails", + "nodeType": "VariableDeclaration", + "scope": 20705, + "src": "2301:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20700, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "2301:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20703, + "indexed": false, + "name": "_newDetails", + "nodeType": "VariableDeclaration", + "scope": 20705, + "src": "2321:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20702, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "2321:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2300:40:59" + }, + "src": "2273:68:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20711, + "name": "LogGranularityChanged", + "nodeType": "EventDefinition", + "parameters": { + "id": 20710, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20707, + "indexed": false, + "name": "_oldGranularity", + "nodeType": "VariableDeclaration", + "scope": 20711, + "src": "2419:23:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20706, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2419:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20709, + "indexed": false, + "name": "_newGranularity", + "nodeType": "VariableDeclaration", + "scope": 20711, + "src": "2444:23:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20708, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2444:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2418:50:59" + }, + "src": "2391:78:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20719, + "name": "LogModuleRemoved", + "nodeType": "EventDefinition", + "parameters": { + "id": 20718, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20713, + "indexed": true, + "name": "_type", + "nodeType": "VariableDeclaration", + "scope": 20719, + "src": "2556:19:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20712, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "2556:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20715, + "indexed": false, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 20719, + "src": "2577:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20714, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2577:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20717, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20719, + "src": "2594:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20716, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2594:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2555:58:59" + }, + "src": "2533:81:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20727, + "name": "LogModuleBudgetChanged", + "nodeType": "EventDefinition", + "parameters": { + "id": 20726, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20721, + "indexed": true, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 20727, + "src": "2709:25:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20720, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "2709:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20723, + "indexed": false, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 20727, + "src": "2736:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20722, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2736:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20725, + "indexed": false, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 20727, + "src": "2753:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20724, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2753:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2708:61:59" + }, + "src": "2680:90:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20733, + "name": "LogFreezeTransfers", + "nodeType": "EventDefinition", + "parameters": { + "id": 20732, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20729, + "indexed": false, + "name": "_freeze", + "nodeType": "VariableDeclaration", + "scope": 20733, + "src": "2846:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20728, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2846:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20731, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20733, + "src": "2860:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20730, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2860:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2845:34:59" + }, + "src": "2821:59:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20739, + "name": "LogCheckpointCreated", + "nodeType": "EventDefinition", + "parameters": { + "id": 20738, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20735, + "indexed": true, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 20739, + "src": "2952:29:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20734, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2952:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20737, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20739, + "src": "2983:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20736, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2983:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "2951:51:59" + }, + "src": "2925:78:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20743, + "name": "LogFinishMintingIssuer", + "nodeType": "EventDefinition", + "parameters": { + "id": 20742, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20741, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20743, + "src": "3094:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20740, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3094:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3093:20:59" + }, + "src": "3065:49:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20747, + "name": "LogFinishMintingSTO", + "nodeType": "EventDefinition", + "parameters": { + "id": 20746, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20745, + "indexed": false, + "name": "_timestamp", + "nodeType": "VariableDeclaration", + "scope": 20747, + "src": "3200:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20744, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3200:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3199:20:59" + }, + "src": "3174:46:59" + }, + { + "anonymous": false, + "documentation": null, + "id": 20753, + "name": "LogChangeSTRAddress", + "nodeType": "EventDefinition", + "parameters": { + "id": 20752, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20749, + "indexed": true, + "name": "_oldAddress", + "nodeType": "VariableDeclaration", + "scope": 20753, + "src": "3307:27:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20748, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3307:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20751, + "indexed": true, + "name": "_newAddress", + "nodeType": "VariableDeclaration", + "scope": 20753, + "src": "3336:27:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20750, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3336:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3306:58:59" + }, + "src": "3281:84:59" + }, + { + "body": { + "id": 20833, + "nodeType": "Block", + "src": "3622:675:59", + "statements": [ + { + "assignments": [ + 20760 + ], + "declarations": [ + { + "constant": false, + "id": 20760, + "name": "isModuleType", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3682:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20759, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3682:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20762, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 20761, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3702:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "3682:25:59" + }, + { + "body": { + "id": 20791, + "nodeType": "Block", + "src": "3773:109:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 20789, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 20776, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "3787:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 20788, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20777, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "3802:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20786, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20778, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "3819:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 20780, + "indexExpression": { + "argumentTypes": null, + "id": 20779, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3827:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3819:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 20782, + "indexExpression": { + "argumentTypes": null, + "id": 20781, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20764, + "src": "3840:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3819:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 20783, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "3819:37:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20784, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "3860:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20785, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3860:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3819:51:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 20787, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "3818:53:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3802:69:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3787:84:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20790, + "nodeType": "ExpressionStatement", + "src": "3787:84:59" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20772, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20767, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20764, + "src": "3735:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20768, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "3739:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 20770, + "indexExpression": { + "argumentTypes": null, + "id": 20769, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3747:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3739:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 20771, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3739:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3735:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20792, + "initializationExpression": { + "assignments": [ + 20764 + ], + "declarations": [ + { + "constant": false, + "id": 20764, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3722:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20763, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "3722:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20766, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 20765, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3732:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "3722:11:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 20774, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "3768:3:59", + "subExpression": { + "argumentTypes": null, + "id": 20773, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20764, + "src": "3768:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 20775, + "nodeType": "ExpressionStatement", + "src": "3768:3:59" + }, + "nodeType": "ForStatement", + "src": "3717:165:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 20796, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20793, + "name": "_fallback", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20757, + "src": "3895:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "id": 20795, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "3908:13:59", + "subExpression": { + "argumentTypes": null, + "id": 20794, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "3909:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3895:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 20830, + "nodeType": "Block", + "src": "4197:83:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20826, + "name": "isModuleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20760, + "src": "4219:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "53656e646572206973206e6f7420636f7272656374206d6f64756c652074797065", + "id": 20827, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4233:35:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_18ea84476249f5cf0264794bb4497de0f9386f65e85fd6aa7b9a26fda3f47826", + "typeString": "literal_string \"Sender is not correct module type\"" + }, + "value": "Sender is not correct module type" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_18ea84476249f5cf0264794bb4497de0f9386f65e85fd6aa7b9a26fda3f47826", + "typeString": "literal_string \"Sender is not correct module type\"" + } + ], + "id": 20825, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4211:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20828, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4211:58:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20829, + "nodeType": "ExpressionStatement", + "src": "4211:58:59" + } + ] + }, + "id": 20831, + "nodeType": "IfStatement", + "src": "3891:389:59", + "trueBody": { + "id": 20824, + "nodeType": "Block", + "src": "3923:268:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 20799, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20797, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3941:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20798, + "name": "STO_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10025, + "src": "3956:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "3941:22:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20819, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20816, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "4137:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20817, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "4137:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20818, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "4151:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4137:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "53656e646572206973206e6f74206f776e6572", + "id": 20820, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4158:21:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c31e61005312bc4f751533ef9aaa8e9a41448b72bb628fe51500ef66060b25c4", + "typeString": "literal_string \"Sender is not owner\"" + }, + "value": "Sender is not owner" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c31e61005312bc4f751533ef9aaa8e9a41448b72bb628fe51500ef66060b25c4", + "typeString": "literal_string \"Sender is not owner\"" + } + ], + "id": 20815, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4129:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20821, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4129:51:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20822, + "nodeType": "ExpressionStatement", + "src": "4129:51:59" + }, + "id": 20823, + "nodeType": "IfStatement", + "src": "3937:243:59", + "trueBody": { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 20811, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20806, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20801, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "3989:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 20803, + "indexExpression": { + "argumentTypes": null, + "id": 20802, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20755, + "src": "3997:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3989:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 20804, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "3989:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 20805, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4020:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "3989:32:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20810, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20807, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "4025:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20808, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "4025:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20809, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "4039:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4025:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3989:55:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "53656e646572206973206e6f74206f776e6572206f722053544f206d6f64756c65206973206174746163686564", + "id": 20812, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4046:47:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_27aa5ed9c12058eab3c15a7622391d8d8cf66ea7b8ce97824ef531556d7ebbe2", + "typeString": "literal_string \"Sender is not owner or STO module is attached\"" + }, + "value": "Sender is not owner or STO module is attached" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_27aa5ed9c12058eab3c15a7622391d8d8cf66ea7b8ce97824ef531556d7ebbe2", + "typeString": "literal_string \"Sender is not owner or STO module is attached\"" + } + ], + "id": 20800, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "3981:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20813, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3981:113:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20814, + "nodeType": "ExpressionStatement", + "src": "3981:113:59" + } + } + ] + } + }, + { + "id": 20832, + "nodeType": "PlaceholderStatement", + "src": "4289:1:59" + } + ] + }, + "documentation": null, + "id": 20834, + "name": "onlyModule", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 20758, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20755, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3587:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20754, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "3587:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20757, + "name": "_fallback", + "nodeType": "VariableDeclaration", + "scope": 20834, + "src": "3606:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 20756, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3606:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "3586:35:59" + }, + "src": "3567:730:59", + "visibility": "internal" + }, + { + "body": { + "id": 20848, + "nodeType": "Block", + "src": "4346:118:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20843, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 20841, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 20839, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20836, + "src": "4364:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "%", + "rightExpression": { + "argumentTypes": null, + "id": 20840, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "4374:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4364:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 20842, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4389:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4364:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "556e61626c6520746f206d6f6469667920746f6b656e2062616c616e6365732061742074686973206772616e756c6172697479", + "id": 20844, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4392:53:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_58b4cb5c3b872c2661ef43443d2a3bc9a81f03995da6b03c67ed8d670b6a9a2c", + "typeString": "literal_string \"Unable to modify token balances at this granularity\"" + }, + "value": "Unable to modify token balances at this granularity" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_58b4cb5c3b872c2661ef43443d2a3bc9a81f03995da6b03c67ed8d670b6a9a2c", + "typeString": "literal_string \"Unable to modify token balances at this granularity\"" + } + ], + "id": 20838, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4356:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20845, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4356:90:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20846, + "nodeType": "ExpressionStatement", + "src": "4356:90:59" + }, + { + "id": 20847, + "nodeType": "PlaceholderStatement", + "src": "4456:1:59" + } + ] + }, + "documentation": null, + "id": 20849, + "name": "checkGranularity", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 20837, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20836, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 20849, + "src": "4329:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20835, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4329:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "4328:17:59" + }, + "src": "4303:161:59", + "visibility": "internal" + }, + { + "body": { + "id": 20871, + "nodeType": "Block", + "src": "4703:233:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 20854, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 20851, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "4717:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 20852, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "4717:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 20853, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "4731:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4717:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 20868, + "nodeType": "Block", + "src": "4834:85:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20864, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4856:19:59", + "subExpression": { + "argumentTypes": null, + "id": 20863, + "name": "finishedSTOMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20667, + "src": "4857:18:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d696e74696e672069732066696e697368656420666f722053544f73", + "id": 20865, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4877:30:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_1b2eb8774382bd7c01e52ec9b26ebd3d636110a215a12592de5928013b58c623", + "typeString": "literal_string \"Minting is finished for STOs\"" + }, + "value": "Minting is finished for STOs" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_1b2eb8774382bd7c01e52ec9b26ebd3d636110a215a12592de5928013b58c623", + "typeString": "literal_string \"Minting is finished for STOs\"" + } + ], + "id": 20862, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4848:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20866, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4848:60:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20867, + "nodeType": "ExpressionStatement", + "src": "4848:60:59" + } + ] + }, + "id": 20869, + "nodeType": "IfStatement", + "src": "4713:206:59", + "trueBody": { + "id": 20861, + "nodeType": "Block", + "src": "4738:90:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20857, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "4760:22:59", + "subExpression": { + "argumentTypes": null, + "id": 20856, + "name": "finishedIssuerMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20664, + "src": "4761:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d696e74696e672069732066696e697368656420666f7220497373756572", + "id": 20858, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4784:32:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c19de2e165bb1c8a94b3685a5659527ec56c0c30abe571d67de7f55d580e920e", + "typeString": "literal_string \"Minting is finished for Issuer\"" + }, + "value": "Minting is finished for Issuer" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c19de2e165bb1c8a94b3685a5659527ec56c0c30abe571d67de7f55d580e920e", + "typeString": "literal_string \"Minting is finished for Issuer\"" + } + ], + "id": 20855, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "4752:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 20859, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4752:65:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20860, + "nodeType": "ExpressionStatement", + "src": "4752:65:59" + } + ] + } + }, + { + "id": 20870, + "nodeType": "PlaceholderStatement", + "src": "4928:1:59" + } + ] + }, + "documentation": null, + "id": 20872, + "name": "isMintingAllowed", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 20850, + "nodeType": "ParameterList", + "parameters": [], + "src": "4700:2:59" + }, + "src": "4675:261:59", + "visibility": "internal" + }, + { + "body": { + "id": 20946, + "nodeType": "Block", + "src": "5628:486:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 20895, + "name": "updateFromRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 675, + "src": "5689:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 20896, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5689:20:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20897, + "nodeType": "ExpressionStatement", + "src": "5689:20:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20900, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 20898, + "name": "tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9948, + "src": "5719:12:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 20899, + "name": "_tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20882, + "src": "5734:13:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + "src": "5719:28:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "id": 20901, + "nodeType": "ExpressionStatement", + "src": "5719:28:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20904, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 20902, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "5757:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 20903, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20880, + "src": "5771:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5757:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 20905, + "nodeType": "ExpressionStatement", + "src": "5757:26:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20914, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20906, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "5793:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20912, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7472616e7366657228616464726573732c75696e7432353629", + "id": 20909, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5828:27:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b", + "typeString": "literal_string \"transfer(address,uint256)\"" + }, + "value": "transfer(address,uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b", + "typeString": "literal_string \"transfer(address,uint256)\"" + } + ], + "id": 20908, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "5818:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20910, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5818:38:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20907, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5811:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20911, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5811:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "5793:65:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20913, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5861:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5793:72:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20915, + "nodeType": "ExpressionStatement", + "src": "5793:72:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20924, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20916, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "5875:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20922, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "7472616e7366657246726f6d28616464726573732c616464726573732c75696e7432353629", + "id": 20919, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5910:39:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_23b872dd7302113369cda2901243429419bec145408fa8b352b3dd92b66c680b", + "typeString": "literal_string \"transferFrom(address,address,uint256)\"" + }, + "value": "transferFrom(address,address,uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_23b872dd7302113369cda2901243429419bec145408fa8b352b3dd92b66c680b", + "typeString": "literal_string \"transferFrom(address,address,uint256)\"" + } + ], + "id": 20918, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "5900:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20920, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5900:50:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20917, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5893:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20921, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5893:58:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "5875:77:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20923, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5955:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5875:84:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20925, + "nodeType": "ExpressionStatement", + "src": "5875:84:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20934, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20926, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "5969:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20932, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "6d696e7428616464726573732c75696e7432353629", + "id": 20929, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6004:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f2842", + "typeString": "literal_string \"mint(address,uint256)\"" + }, + "value": "mint(address,uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_40c10f19c047ae7dfa66d6312b683d2ea3dfbcb4159e96b967c5f4b0a86f2842", + "typeString": "literal_string \"mint(address,uint256)\"" + } + ], + "id": 20928, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "5994:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20930, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5994:34:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20927, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5987:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20931, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5987:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "5969:61:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20933, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6033:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "5969:68:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20935, + "nodeType": "ExpressionStatement", + "src": "5969:68:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 20944, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 20936, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "6047:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 20942, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "6275726e2875696e7432353629", + "id": 20939, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6082:15:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_42966c689b5afe9b9b3f8a7103b2a19980d59629bfd6a20a60972312ed41d836", + "typeString": "literal_string \"burn(uint256)\"" + }, + "value": "burn(uint256)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_42966c689b5afe9b9b3f8a7103b2a19980d59629bfd6a20a60972312ed41d836", + "typeString": "literal_string \"burn(uint256)\"" + } + ], + "id": 20938, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23302, + "src": "6072:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_sha3_pure$__$returns$_t_bytes32_$", + "typeString": "function () pure returns (bytes32)" + } + }, + "id": 20940, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6072:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 20937, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "6065:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 20941, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6065:34:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "6047:53:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 20943, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6103:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "6047:60:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 20945, + "nodeType": "ExpressionStatement", + "src": "6047:60:59" + } + ] + }, + "documentation": "@notice Constructor\n@param _name Name of the SecurityToken\n@param _symbol Symbol of the Token\n@param _decimals Decimals for the securityToken\n@param _granularity granular level of the token\n@param _tokenDetails Details of the token that are stored off-chain (IPFS hash)\n@param _polymathRegistry Contract address of the polymath registry", + "id": 20947, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 20887, + "name": "_name", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20874, + "src": "5558:5:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 20888, + "name": "_symbol", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20876, + "src": "5565:7:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "argumentTypes": null, + "id": 20889, + "name": "_decimals", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20878, + "src": "5574:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 20890, + "modifierName": { + "argumentTypes": null, + "id": 20886, + "name": "DetailedERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22971, + "src": "5544:13:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_DetailedERC20_$22971_$", + "typeString": "type(contract DetailedERC20)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5544:40:59" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 20892, + "name": "_polymathRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20884, + "src": "5605:17:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 20893, + "modifierName": { + "argumentTypes": null, + "id": 20891, + "name": "RegistryUpdater", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 676, + "src": "5589:15:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_RegistryUpdater_$676_$", + "typeString": "type(contract RegistryUpdater)" + } + }, + "nodeType": "ModifierInvocation", + "src": "5589:34:59" + } + ], + "name": "", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 20885, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20874, + "name": "_name", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5366:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20873, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "5366:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20876, + "name": "_symbol", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5388:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20875, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "5388:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20878, + "name": "_decimals", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5412:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20877, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "5412:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20880, + "name": "_granularity", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5437:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20879, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5437:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20882, + "name": "_tokenDetails", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5467:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 20881, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "5467:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20884, + "name": "_polymathRegistry", + "nodeType": "VariableDeclaration", + "scope": 20947, + "src": "5497:25:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20883, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5497:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "5356:172:59" + }, + "payable": false, + "returnParameters": { + "id": 20894, + "nodeType": "ParameterList", + "parameters": [], + "src": "5628:0:59" + }, + "scope": 22534, + "src": "5344:770:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 20969, + "nodeType": "Block", + "src": "6652:69:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20963, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20949, + "src": "6673:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 20964, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20951, + "src": "6689:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "argumentTypes": null, + "id": 20965, + "name": "_maxCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20953, + "src": "6696:8:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 20966, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20955, + "src": "6706:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 20962, + "name": "_addModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21079, + "src": "6662:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (address,bytes memory,uint256,uint256)" + } + }, + "id": 20967, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6662:52:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20968, + "nodeType": "ExpressionStatement", + "src": "6662:52:59" + } + ] + }, + "documentation": "@notice Function used to attach the module in security token\n@param _moduleFactory Contract address of the module factory that needs to be attached\n@param _data Data used for the intialization of the module factory variables\n@param _maxCost Maximum cost of the Module factory\n@param _budget Budget of the Module factory", + "id": 20970, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 20958, + "modifierName": { + "argumentTypes": null, + "id": 20957, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "6629:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "6629:9:59" + }, + { + "arguments": null, + "id": 20960, + "modifierName": { + "argumentTypes": null, + "id": 20959, + "name": "nonReentrant", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22589, + "src": "6639:12:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "6639:12:59" + } + ], + "name": "addModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 20956, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20949, + "name": "_moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6519:22:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20948, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6519:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20951, + "name": "_data", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6551:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 20950, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "6551:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20953, + "name": "_maxCost", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6572:16:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20952, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6572:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20955, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 20970, + "src": "6598:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20954, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6598:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "6509:110:59" + }, + "payable": false, + "returnParameters": { + "id": 20961, + "nodeType": "ParameterList", + "parameters": [], + "src": "6652:0:59" + }, + "scope": 22534, + "src": "6491:230:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 21078, + "nodeType": "Block", + "src": "7506:1172:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20985, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "7628:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20982, + "name": "moduleRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 609, + "src": "7602:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 20981, + "name": "IModuleRegistry", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9915, + "src": "7586:15:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModuleRegistry_$9915_$", + "typeString": "type(contract IModuleRegistry)" + } + }, + "id": 20983, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7586:31:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleRegistry_$9915", + "typeString": "contract IModuleRegistry" + } + }, + "id": 20984, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "useModule", + "nodeType": "MemberAccess", + "referencedDeclaration": 9899, + "src": "7586:41:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$returns$__$", + "typeString": "function (address) external" + } + }, + "id": 20986, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7586:57:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 20987, + "nodeType": "ExpressionStatement", + "src": "7586:57:59" + }, + { + "assignments": [ + 20989 + ], + "declarations": [ + { + "constant": false, + "id": 20989, + "name": "moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7653:28:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + }, + "typeName": { + "contractScope": null, + "id": 20988, + "name": "IModuleFactory", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 9892, + "src": "7653:14:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20993, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 20991, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "7699:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 20990, + "name": "IModuleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9892, + "src": "7684:14:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModuleFactory_$9892_$", + "typeString": "type(contract IModuleFactory)" + } + }, + "id": 20992, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7684:30:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7653:61:59" + }, + { + "assignments": [ + 20995 + ], + "declarations": [ + { + "constant": false, + "id": 20995, + "name": "moduleType", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7724:16:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 20994, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "7724:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 20999, + "initialValue": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "id": 20996, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "7743:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 20997, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getType", + "nodeType": "MemberAccess", + "referencedDeclaration": 9747, + "src": "7743:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint8_$", + "typeString": "function () view external returns (uint8)" + } + }, + "id": 20998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7743:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7724:42:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21006, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21001, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "7784:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21003, + "indexExpression": { + "argumentTypes": null, + "id": 21002, + "name": "moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20995, + "src": "7792:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "7784:19:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21004, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "7784:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 21005, + "name": "MAX_MODULES", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20679, + "src": "7813:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "7784:40:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4c696d6974206f66204d4158204d4f44554c45532069732072656163686564", + "id": 21007, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7826:33:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_22dca6cc98b2f56663821f48152354d934949af366941128c128092fc385789b", + "typeString": "literal_string \"Limit of MAX MODULES is reached\"" + }, + "value": "Limit of MAX MODULES is reached" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_22dca6cc98b2f56663821f48152354d934949af366941128c128092fc385789b", + "typeString": "literal_string \"Limit of MAX MODULES is reached\"" + } + ], + "id": 21000, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "7776:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21008, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7776:84:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21009, + "nodeType": "ExpressionStatement", + "src": "7776:84:59" + }, + { + "assignments": [ + 21011 + ], + "declarations": [ + { + "constant": false, + "id": 21011, + "name": "moduleCost", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7870:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21010, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7870:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21015, + "initialValue": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "id": 21012, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "7891:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 21013, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "setupCost", + "nodeType": "MemberAccess", + "referencedDeclaration": 9665, + "src": "7891:23:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + } + }, + "id": 21014, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7891:25:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7870:46:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21019, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21017, + "name": "moduleCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21011, + "src": "7934:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 21018, + "name": "_maxCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20976, + "src": "7948:8:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7934:22:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d617820436f737420697320616c776179732062652067726561746572207468616e206d6f64756c6520636f7374", + "id": 21020, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7958:48:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_90bdcbd1eae82678b05a05785b42cb078a37b23efb50052519b8f8f8daee9e4f", + "typeString": "literal_string \"Max Cost is always be greater than module cost\"" + }, + "value": "Max Cost is always be greater than module cost" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_90bdcbd1eae82678b05a05785b42cb078a37b23efb50052519b8f8f8daee9e4f", + "typeString": "literal_string \"Max Cost is always be greater than module cost\"" + } + ], + "id": 21016, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "7926:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21021, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "7926:81:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21022, + "nodeType": "ExpressionStatement", + "src": "7926:81:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21028, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "8083:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21029, + "name": "moduleCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21011, + "src": "8099:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21025, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "8064:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21024, + "name": "ERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23014, + "src": "8058:5:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ERC20_$23014_$", + "typeString": "type(contract ERC20)" + } + }, + "id": 21026, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8058:16:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$23014", + "typeString": "contract ERC20" + } + }, + "id": 21027, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "approve", + "nodeType": "MemberAccess", + "referencedDeclaration": 23005, + "src": "8058:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21030, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8058:52:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4e6f742061626c6520746f20617070726f766520746865206d6f64756c6520636f7374", + "id": 21031, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8112:37:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_11ebda84b718c1e17032ff96739c6d6235706a8e1578218e5e6f4a7e2005eab5", + "typeString": "literal_string \"Not able to approve the module cost\"" + }, + "value": "Not able to approve the module cost" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_11ebda84b718c1e17032ff96739c6d6235706a8e1578218e5e6f4a7e2005eab5", + "typeString": "literal_string \"Not able to approve the module cost\"" + } + ], + "id": 21023, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "8050:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21032, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8050:100:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21033, + "nodeType": "ExpressionStatement", + "src": "8050:100:59" + }, + { + "assignments": [ + 21035 + ], + "declarations": [ + { + "constant": false, + "id": 21035, + "name": "module", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "8210:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21034, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8210:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21040, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21038, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20974, + "src": "8248:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 21036, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "8227:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 21037, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "deploy", + "nodeType": "MemberAccess", + "referencedDeclaration": 9742, + "src": "8227:20:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_bytes_memory_ptr_$returns$_t_address_$", + "typeString": "function (bytes memory) external returns (address)" + } + }, + "id": 21039, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8227:27:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "8210:44:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21046, + "name": "module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21035, + "src": "8330:6:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21047, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20978, + "src": "8338:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21043, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "8311:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21042, + "name": "ERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23014, + "src": "8305:5:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ERC20_$23014_$", + "typeString": "type(contract ERC20)" + } + }, + "id": 21044, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8305:16:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$23014", + "typeString": "contract ERC20" + } + }, + "id": 21045, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "approve", + "nodeType": "MemberAccess", + "referencedDeclaration": 23005, + "src": "8305:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21048, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8305:41:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4e6f742061626c6520746f20617070726f76652074686520627564676574", + "id": 21049, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8348:32:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_524ae74447c5c157d26c458a70f19c36827828baf5b9a2964a7996292f367fcf", + "typeString": "literal_string \"Not able to approve the budget\"" + }, + "value": "Not able to approve the budget" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_524ae74447c5c157d26c458a70f19c36827828baf5b9a2964a7996292f367fcf", + "typeString": "literal_string \"Not able to approve the budget\"" + } + ], + "id": 21041, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "8297:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21050, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8297:84:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21051, + "nodeType": "ExpressionStatement", + "src": "8297:84:59" + }, + { + "assignments": [ + 21053 + ], + "declarations": [ + { + "constant": false, + "id": 21053, + "name": "moduleName", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "8433:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21052, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8433:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21057, + "initialValue": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "argumentTypes": null, + "id": 21054, + "name": "moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20989, + "src": "8454:13:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IModuleFactory_$9892", + "typeString": "contract IModuleFactory" + } + }, + "id": 21055, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "getName", + "nodeType": "MemberAccess", + "referencedDeclaration": 9752, + "src": "8454:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_bytes32_$", + "typeString": "function () view external returns (bytes32)" + } + }, + "id": 21056, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8454:23:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "8433:44:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21063, + "name": "moduleName", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21053, + "src": "8523:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 21064, + "name": "module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21035, + "src": "8535:6:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21062, + "name": "ModuleData", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20648, + "src": "8512:10:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_ModuleData_$20648_storage_ptr_$", + "typeString": "type(struct SecurityToken.ModuleData storage pointer)" + } + }, + "id": 21065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8512:30:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_memory", + "typeString": "struct SecurityToken.ModuleData memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_ModuleData_$20648_memory", + "typeString": "struct SecurityToken.ModuleData memory" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21058, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "8487:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21060, + "indexExpression": { + "argumentTypes": null, + "id": 21059, + "name": "moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20995, + "src": "8495:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "8487:19:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21061, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "8487:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_struct$_ModuleData_$20648_storage_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.ModuleData storage ref) returns (uint256)" + } + }, + "id": 21066, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8487:56:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21067, + "nodeType": "ExpressionStatement", + "src": "8487:56:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21069, + "name": "moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20995, + "src": "8598:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "id": 21070, + "name": "moduleName", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21053, + "src": "8610:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "id": 21071, + "name": "_moduleFactory", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20972, + "src": "8622:14:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21072, + "name": "module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21035, + "src": "8638:6:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21073, + "name": "moduleCost", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21011, + "src": "8646:10:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21074, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20978, + "src": "8658:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21075, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "8667:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21068, + "name": "LogModuleAdded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20699, + "src": "8583:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint8_$_t_bytes32_$_t_address_$_t_address_$_t_uint256_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint8,bytes32,address,address,uint256,uint256,uint256)" + } + }, + "id": 21076, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8583:88:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21077, + "nodeType": "EmitStatement", + "src": "8578:93:59" + } + ] + }, + "documentation": "@notice _addModule handles the attachment (or replacement) of modules for the ST\n@dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it\n@dev to control restrictions on transfers.\n@dev You are allowed to add a new moduleType if:\n@dev - there is no existing module of that type yet added\n@dev - the last member of the module list is replacable\n@param _moduleFactory is the address of the module factory to be added\n@param _data is data packed into bytes used to further configure the module (See STO usage)\n@param _maxCost max amount of POLY willing to pay to module. (WIP)", + "id": 21079, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "_addModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 20979, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 20972, + "name": "_moduleFactory", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7425:22:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 20971, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "7425:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20974, + "name": "_data", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7449:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 20973, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "7449:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20976, + "name": "_maxCost", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7462:16:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20975, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7462:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 20978, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 21079, + "src": "7480:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20977, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7480:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "7424:72:59" + }, + "payable": false, + "returnParameters": { + "id": 20980, + "nodeType": "ParameterList", + "parameters": [], + "src": "7506:0:59" + }, + "scope": 22534, + "src": "7405:1273:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21152, + "nodeType": "Block", + "src": "8989:649:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21094, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21089, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9007:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21090, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9022:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21092, + "indexExpression": { + "argumentTypes": null, + "id": 21091, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9030:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9022:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21093, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9022:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9007:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d6f64756c6520696e64657820646f65736e277420657869737420617320706572207468652063686f6f73656e206d6f64756c652074797065", + "id": 21095, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9059:59:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2c2b71fb37297b532fe6ad2499a7624af6231a453bb6b813ec9dd531487fa7d5", + "typeString": "literal_string \"Module index doesn't exist as per the choosen module type\"" + }, + "value": "Module index doesn't exist as per the choosen module type" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2c2b71fb37297b532fe6ad2499a7624af6231a453bb6b813ec9dd531487fa7d5", + "typeString": "literal_string \"Module index doesn't exist as per the choosen module type\"" + } + ], + "id": 21088, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "8999:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21096, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "8999:120:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21097, + "nodeType": "ExpressionStatement", + "src": "8999:120:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21108, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21099, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9137:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21101, + "indexExpression": { + "argumentTypes": null, + "id": 21100, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9145:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9137:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21103, + "indexExpression": { + "argumentTypes": null, + "id": 21102, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9158:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9137:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21104, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "9137:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21106, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9197:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21105, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "9189:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21107, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9189:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "9137:62:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d6f64756c6520636f6e747261637420616464726573732073686f756c64206e6f74206265203078", + "id": 21109, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9209:42:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2079f97d089efa5c6ae574cb5c749cfd9f6fe18b9702363bcb14091aec9a3ff9", + "typeString": "literal_string \"Module contract address should not be 0x\"" + }, + "value": "Module contract address should not be 0x" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2079f97d089efa5c6ae574cb5c749cfd9f6fe18b9702363bcb14091aec9a3ff9", + "typeString": "literal_string \"Module contract address should not be 0x\"" + } + ], + "id": 21098, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "9129:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21110, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9129:123:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21111, + "nodeType": "ExpressionStatement", + "src": "9129:123:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21113, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9393:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21114, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9406:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21116, + "indexExpression": { + "argumentTypes": null, + "id": 21115, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9414:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9406:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21118, + "indexExpression": { + "argumentTypes": null, + "id": 21117, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9427:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9406:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21119, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "9406:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21120, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "9456:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21112, + "name": "LogModuleRemoved", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20719, + "src": "9376:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint8_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (uint8,address,uint256)" + } + }, + "id": 21121, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "9376:84:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21122, + "nodeType": "EmitStatement", + "src": "9371:89:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21138, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21123, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9470:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21126, + "indexExpression": { + "argumentTypes": null, + "id": 21124, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9478:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9470:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21127, + "indexExpression": { + "argumentTypes": null, + "id": 21125, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21083, + "src": "9491:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "9470:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21128, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9507:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21130, + "indexExpression": { + "argumentTypes": null, + "id": 21129, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9515:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9507:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21137, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21136, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21131, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9528:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21133, + "indexExpression": { + "argumentTypes": null, + "id": 21132, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9536:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9528:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21134, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9528:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21135, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9558:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9528:31:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9507:53:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "src": "9470:90:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21139, + "nodeType": "ExpressionStatement", + "src": "9470:90:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21150, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21140, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9570:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21142, + "indexExpression": { + "argumentTypes": null, + "id": 21141, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9578:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9570:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21143, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9570:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21149, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21144, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "9600:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21146, + "indexExpression": { + "argumentTypes": null, + "id": 21145, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21081, + "src": "9608:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "9600:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21147, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "9600:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21148, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9630:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "9600:31:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "9570:61:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21151, + "nodeType": "ExpressionStatement", + "src": "9570:61:59" + } + ] + }, + "documentation": "@notice Removes a module attached to the SecurityToken\n@param _moduleType is which type of module we are trying to remove\n@param _moduleIndex is the index of the module within the chosen type", + "id": 21153, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21086, + "modifierName": { + "argumentTypes": null, + "id": 21085, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "8979:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "8979:9:59" + } + ], + "name": "removeModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21084, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21081, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21153, + "src": "8931:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21080, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "8931:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21083, + "name": "_moduleIndex", + "nodeType": "VariableDeclaration", + "scope": 21153, + "src": "8950:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21082, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "8950:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "8930:39:59" + }, + "payable": false, + "returnParameters": { + "id": 21087, + "nodeType": "ParameterList", + "parameters": [], + "src": "8989:0:59" + }, + "scope": 22534, + "src": "8909:729:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + { + "body": { + "id": 21193, + "nodeType": "Block", + "src": "10003:277:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21169, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21164, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10017:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21166, + "indexExpression": { + "argumentTypes": null, + "id": 21165, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21155, + "src": "10025:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10017:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21167, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10017:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21168, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10047:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10017:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 21191, + "nodeType": "Block", + "src": "10225:48:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "hexValue": "", + "id": 21185, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10247:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21187, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10259:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21186, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "10251:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21188, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "10251:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21189, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10246:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_$_t_address_$", + "typeString": "tuple(literal_string \"\",address)" + } + }, + "functionReturnParameters": 21163, + "id": 21190, + "nodeType": "Return", + "src": "10239:23:59" + } + ] + }, + "id": 21192, + "nodeType": "IfStatement", + "src": "10013:260:59", + "trueBody": { + "id": 21184, + "nodeType": "Block", + "src": "10050:169:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21170, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10089:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21172, + "indexExpression": { + "argumentTypes": null, + "id": 21171, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21155, + "src": "10097:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10089:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21174, + "indexExpression": { + "argumentTypes": null, + "id": 21173, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21157, + "src": "10110:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10089:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21175, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "name", + "nodeType": "MemberAccess", + "referencedDeclaration": 20645, + "src": "10089:39:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21176, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10146:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21178, + "indexExpression": { + "argumentTypes": null, + "id": 21177, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21155, + "src": "10154:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10146:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21180, + "indexExpression": { + "argumentTypes": null, + "id": 21179, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21157, + "src": "10167:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10146:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21181, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "10146:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21182, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10071:137:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$", + "typeString": "tuple(bytes32,address)" + } + }, + "functionReturnParameters": 21163, + "id": 21183, + "nodeType": "Return", + "src": "10064:144:59" + } + ] + } + } + ] + }, + "documentation": "@notice Returns module list for a module type\n@param _moduleType is which type of module we are trying to get\n@param _moduleIndex is the index of the module within the chosen type\n@return bytes32\n@return address", + "id": 21194, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getModule", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21158, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21155, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9926:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21154, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "9926:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21157, + "name": "_moduleIndex", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9945:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21156, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "9945:4:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9925:38:59" + }, + "payable": false, + "returnParameters": { + "id": 21163, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21160, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9985:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21159, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9985:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21162, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21194, + "src": "9994:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21161, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9994:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "9984:18:59" + }, + "scope": 22534, + "src": "9907:373:59", + "stateMutability": "view", + "superFunction": 10059, + "visibility": "public" + }, + { + "body": { + "id": 21265, + "nodeType": "Block", + "src": "10665:480:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21210, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21205, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10679:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21207, + "indexExpression": { + "argumentTypes": null, + "id": 21206, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10687:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10679:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21208, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10679:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21209, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10709:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "10679:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 21263, + "nodeType": "Block", + "src": "11091:48:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "hexValue": "", + "id": 21257, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11113:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21259, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11125:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21258, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "11117:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21260, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11117:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21261, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "11112:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_$_t_address_$", + "typeString": "tuple(literal_string \"\",address)" + } + }, + "functionReturnParameters": 21204, + "id": 21262, + "nodeType": "Return", + "src": "11105:23:59" + } + ] + }, + "id": 21264, + "nodeType": "IfStatement", + "src": "10675:464:59", + "trueBody": { + "id": 21256, + "nodeType": "Block", + "src": "10712:373:59", + "statements": [ + { + "body": { + "id": 21248, + "nodeType": "Block", + "src": "10784:254:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 21231, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21224, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10806:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21226, + "indexExpression": { + "argumentTypes": null, + "id": 21225, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10814:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10806:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21228, + "indexExpression": { + "argumentTypes": null, + "id": 21227, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10827:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10806:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21229, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "name", + "nodeType": "MemberAccess", + "referencedDeclaration": 20645, + "src": "10806:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 21230, + "name": "_name", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21198, + "src": "10838:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "10806:37:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21247, + "nodeType": "IfStatement", + "src": "10802:222:59", + "trueBody": { + "id": 21246, + "nodeType": "Block", + "src": "10845:179:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21232, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10896:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21234, + "indexExpression": { + "argumentTypes": null, + "id": 21233, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10904:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10896:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21236, + "indexExpression": { + "argumentTypes": null, + "id": 21235, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10917:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10896:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21237, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "name", + "nodeType": "MemberAccess", + "referencedDeclaration": 20645, + "src": "10896:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21238, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10948:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21240, + "indexExpression": { + "argumentTypes": null, + "id": 21239, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10956:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10948:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21242, + "indexExpression": { + "argumentTypes": null, + "id": 21241, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10969:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10948:23:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21243, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "10948:37:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21244, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "10872:133:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_address_$", + "typeString": "tuple(bytes32,address)" + } + }, + "functionReturnParameters": 21204, + "id": 21245, + "nodeType": "Return", + "src": "10865:140:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21220, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21215, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10746:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21216, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "10750:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21218, + "indexExpression": { + "argumentTypes": null, + "id": 21217, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21196, + "src": "10758:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "10750:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21219, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "10750:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "10746:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21249, + "initializationExpression": { + "assignments": [ + 21212 + ], + "declarations": [ + { + "constant": false, + "id": 21212, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10731:9:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21211, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "10731:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21214, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 21213, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10743:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "10731:13:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 21222, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "10779:3:59", + "subExpression": { + "argumentTypes": null, + "id": 21221, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21212, + "src": "10779:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21223, + "nodeType": "ExpressionStatement", + "src": "10779:3:59" + }, + "nodeType": "ForStatement", + "src": "10726:312:59" + }, + { + "expression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "hexValue": "", + "id": 21250, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11059:2:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "typeString": "literal_string \"\"" + }, + "value": "" + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21252, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11071:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21251, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "11063:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21253, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11063:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "id": 21254, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "11058:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_$_t_address_$", + "typeString": "tuple(literal_string \"\",address)" + } + }, + "functionReturnParameters": 21204, + "id": 21255, + "nodeType": "Return", + "src": "11051:23:59" + } + ] + } + } + ] + }, + "documentation": "@notice returns module list for a module name - will return first match\n@param _moduleType is which type of module we are trying to get\n@param _name is the name of the module within the chosen type\n@return bytes32\n@return address", + "id": 21266, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getModuleByName", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21199, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21196, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10592:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21195, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "10592:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21198, + "name": "_name", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10611:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21197, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10611:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10591:34:59" + }, + "payable": false, + "returnParameters": { + "id": 21204, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21201, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10647:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 21200, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "10647:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21203, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21266, + "src": "10656:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21202, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "10656:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "10646:18:59" + }, + "scope": 22534, + "src": "10567:578:59", + "stateMutability": "view", + "superFunction": 10070, + "visibility": "public" + }, + { + "body": { + "id": 21284, + "nodeType": "Block", + "src": "11460:92:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21278, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22759, + "src": "11504:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21279, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21268, + "src": "11511:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21275, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "11484:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21274, + "name": "ERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23014, + "src": "11478:5:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ERC20_$23014_$", + "typeString": "type(contract ERC20)" + } + }, + "id": 21276, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11478:16:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$23014", + "typeString": "contract ERC20" + } + }, + "id": 21277, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "transfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 23037, + "src": "11478:25:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21280, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11478:41:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e2d73756666696369656e742062616c616e6365", + "id": 21281, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11521:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_30a1bb60a0c6caf3e6f6f7b8691b64b76aa0d2ff7478fc897cfd6f5a122b1b2b", + "typeString": "literal_string \"In-sufficient balance\"" + }, + "value": "In-sufficient balance" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_30a1bb60a0c6caf3e6f6f7b8691b64b76aa0d2ff7478fc897cfd6f5a122b1b2b", + "typeString": "literal_string \"In-sufficient balance\"" + } + ], + "id": 21273, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "11470:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21282, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11470:75:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21283, + "nodeType": "ExpressionStatement", + "src": "11470:75:59" + } + ] + }, + "documentation": "@notice allows the owner to withdraw unspent POLY stored by them on the ST.\n@dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee.\n@param _amount amount of POLY to withdraw", + "id": 21285, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21271, + "modifierName": { + "argumentTypes": null, + "id": 21270, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "11450:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "11450:9:59" + } + ], + "name": "withdrawPoly", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21269, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21268, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 21285, + "src": "11426:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21267, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11426:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "11425:17:59" + }, + "payable": false, + "returnParameters": { + "id": 21272, + "nodeType": "ParameterList", + "parameters": [], + "src": "11460:0:59" + }, + "scope": 22534, + "src": "11404:148:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21385, + "nodeType": "Block", + "src": "11852:835:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 21299, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21297, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "11870:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21298, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11885:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "11870:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d6f64756c6520747970652063616e6e6f74206265207a65726f", + "id": 21300, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11888:28:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_22e5fe8e01473d297e25a2a1aee7f758126121ff74d7fafb2b5bccf21dbd9682", + "typeString": "literal_string \"Module type cannot be zero\"" + }, + "value": "Module type cannot be zero" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_22e5fe8e01473d297e25a2a1aee7f758126121ff74d7fafb2b5bccf21dbd9682", + "typeString": "literal_string \"Module type cannot be zero\"" + } + ], + "id": 21296, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "11862:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21301, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11862:55:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21302, + "nodeType": "ExpressionStatement", + "src": "11862:55:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21309, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21304, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "11935:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21305, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "11950:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21307, + "indexExpression": { + "argumentTypes": null, + "id": 21306, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "11958:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "11950:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21308, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "11950:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "11935:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e636f727272656374206d6f64756c6520696e646578", + "id": 21310, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11979:25:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_246e30dbb9a00692967b4085cbb5fa5d23ee41ba746d906437cdc6324b067ad6", + "typeString": "literal_string \"Incorrrect module index\"" + }, + "value": "Incorrrect module index" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_246e30dbb9a00692967b4085cbb5fa5d23ee41ba746d906437cdc6324b067ad6", + "typeString": "literal_string \"Incorrrect module index\"" + } + ], + "id": 21303, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "11927:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21311, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "11927:78:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21312, + "nodeType": "ExpressionStatement", + "src": "11927:78:59" + }, + { + "assignments": [ + 21314 + ], + "declarations": [ + { + "constant": false, + "id": 21314, + "name": "_currentAllowance", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "12015:25:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21313, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "12015:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21329, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21320, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23373, + "src": "12079:4:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SecurityToken_$22534", + "typeString": "contract SecurityToken" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_SecurityToken_$22534", + "typeString": "contract SecurityToken" + } + ], + "id": 21319, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12071:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21321, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12071:13:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21322, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12086:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21324, + "indexExpression": { + "argumentTypes": null, + "id": 21323, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12094:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12086:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21326, + "indexExpression": { + "argumentTypes": null, + "id": 21325, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12107:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12086:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21327, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12086:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21316, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "12050:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21315, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9492, + "src": "12043:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC20_$9492_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 21317, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12043:17:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IERC20_$9492", + "typeString": "contract IERC20" + } + }, + "id": 21318, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "allowance", + "nodeType": "MemberAccess", + "referencedDeclaration": 22985, + "src": "12043:27:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_address_$_t_address_$returns$_t_uint256_$", + "typeString": "function (address,address) view external returns (uint256)" + } + }, + "id": 21328, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12043:92:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12015:120:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21332, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21330, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12149:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 21331, + "name": "_currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21314, + "src": "12159:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "12149:27:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 21372, + "nodeType": "Block", + "src": "12378:194:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21358, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12435:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21360, + "indexExpression": { + "argumentTypes": null, + "id": 21359, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12443:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12435:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21362, + "indexExpression": { + "argumentTypes": null, + "id": 21361, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12456:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12435:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21363, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12435:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21366, + "name": "_currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21314, + "src": "12497:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21364, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12485:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21365, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "12485:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21367, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12485:30:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21355, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "12407:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21354, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9492, + "src": "12400:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC20_$9492_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 21356, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12400:17:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IERC20_$9492", + "typeString": "contract IERC20" + } + }, + "id": 21357, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "increaseApproval", + "nodeType": "MemberAccess", + "referencedDeclaration": 9491, + "src": "12400:34:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21368, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12400:116:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e73756666696369656e742062616c616e636520746f20696e637265617365417070726f76616c", + "id": 21369, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12518:42:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_3b00cfda6eac0d5cac672a125e339ba8d9ee08603d0d23f305665757678226dc", + "typeString": "literal_string \"Insufficient balance to increaseApproval\"" + }, + "value": "Insufficient balance to increaseApproval" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_3b00cfda6eac0d5cac672a125e339ba8d9ee08603d0d23f305665757678226dc", + "typeString": "literal_string \"Insufficient balance to increaseApproval\"" + } + ], + "id": 21353, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "12392:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21370, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12392:169:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21371, + "nodeType": "ExpressionStatement", + "src": "12392:169:59" + } + ] + }, + "id": 21373, + "nodeType": "IfStatement", + "src": "12145:427:59", + "trueBody": { + "id": 21352, + "nodeType": "Block", + "src": "12178:194:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21338, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12235:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21340, + "indexExpression": { + "argumentTypes": null, + "id": 21339, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12243:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12235:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21342, + "indexExpression": { + "argumentTypes": null, + "id": 21341, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12256:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12235:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21343, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12235:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21346, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12307:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21344, + "name": "_currentAllowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21314, + "src": "12285:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21345, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "12285:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21347, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12285:30:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21335, + "name": "polyToken", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 615, + "src": "12207:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21334, + "name": "IERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9492, + "src": "12200:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC20_$9492_$", + "typeString": "type(contract IERC20)" + } + }, + "id": 21336, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12200:17:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IERC20_$9492", + "typeString": "contract IERC20" + } + }, + "id": 21337, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "decreaseApproval", + "nodeType": "MemberAccess", + "referencedDeclaration": 9482, + "src": "12200:34:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 21348, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12200:116:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e73756666696369656e742062616c616e636520746f206465637265617365417070726f76616c", + "id": 21349, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12318:42:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f1a242750d5ca62923d53471e92c457415e83478e55fbb541dc14993793b903d", + "typeString": "literal_string \"Insufficient balance to decreaseApproval\"" + }, + "value": "Insufficient balance to decreaseApproval" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f1a242750d5ca62923d53471e92c457415e83478e55fbb541dc14993793b903d", + "typeString": "literal_string \"Insufficient balance to decreaseApproval\"" + } + ], + "id": 21333, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "12192:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21350, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12192:169:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21351, + "nodeType": "ExpressionStatement", + "src": "12192:169:59" + } + ] + } + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21375, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12609:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21376, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "12622:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21378, + "indexExpression": { + "argumentTypes": null, + "id": 21377, + "name": "_moduleType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21287, + "src": "12630:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12622:20:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21380, + "indexExpression": { + "argumentTypes": null, + "id": 21379, + "name": "_moduleIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21289, + "src": "12643:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "12622:34:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21381, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "12622:48:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21382, + "name": "_budget", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21291, + "src": "12672:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21374, + "name": "LogModuleBudgetChanged", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20727, + "src": "12586:22:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint8_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (uint8,address,uint256)" + } + }, + "id": 21383, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12586:94:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21384, + "nodeType": "EmitStatement", + "src": "12581:99:59" + } + ] + }, + "documentation": "@notice allows owner to approve more POLY to one of the modules\n@param _moduleType module type\n@param _moduleIndex module index\n@param _budget new budget", + "id": 21386, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21294, + "modifierName": { + "argumentTypes": null, + "id": 21293, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "11842:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "11842:9:59" + } + ], + "name": "changeModuleBudget", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21292, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21287, + "name": "_moduleType", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "11779:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21286, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "11779:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21289, + "name": "_moduleIndex", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "11798:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21288, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "11798:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21291, + "name": "_budget", + "nodeType": "VariableDeclaration", + "scope": 21386, + "src": "11818:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21290, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11818:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "11778:56:59" + }, + "payable": false, + "returnParameters": { + "id": 21295, + "nodeType": "ParameterList", + "parameters": [], + "src": "11852:0:59" + }, + "scope": 22534, + "src": "11751:936:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21402, + "nodeType": "Block", + "src": "12867:116:59", + "statements": [ + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21394, + "name": "tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9948, + "src": "12904:12:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + { + "argumentTypes": null, + "id": 21395, + "name": "_newTokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21388, + "src": "12918:16:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + }, + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + ], + "id": 21393, + "name": "LogUpdateTokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20705, + "src": "12882:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_string_memory_ptr_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (string memory,string memory)" + } + }, + "id": 21396, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "12882:53:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21397, + "nodeType": "EmitStatement", + "src": "12877:58:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21398, + "name": "tokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9948, + "src": "12945:12:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 21399, + "name": "_newTokenDetails", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21388, + "src": "12960:16:59", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + "src": "12945:31:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage", + "typeString": "string storage ref" + } + }, + "id": 21401, + "nodeType": "ExpressionStatement", + "src": "12945:31:59" + } + ] + }, + "documentation": "@notice change the tokenDetails\n@param _newTokenDetails New token details", + "id": 21403, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21391, + "modifierName": { + "argumentTypes": null, + "id": 21390, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "12857:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "12857:9:59" + } + ], + "name": "updateTokenDetails", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21389, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21388, + "name": "_newTokenDetails", + "nodeType": "VariableDeclaration", + "scope": 21403, + "src": "12825:23:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 21387, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "12825:6:59", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "12824:25:59" + }, + "payable": false, + "returnParameters": { + "id": 21392, + "nodeType": "ParameterList", + "parameters": [], + "src": "12867:0:59" + }, + "scope": 22534, + "src": "12797:186:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21426, + "nodeType": "Block", + "src": "13182:170:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21413, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21411, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21405, + "src": "13200:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21412, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13216:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13200:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4772616e756c61726974792063616e206e6f742062652030", + "id": 21414, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13219:26:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2d4731cbc00328ab390123e785f8142f724cfe715c557f1d89e769da378906ce", + "typeString": "literal_string \"Granularity can not be 0\"" + }, + "value": "Granularity can not be 0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2d4731cbc00328ab390123e785f8142f724cfe715c557f1d89e769da378906ce", + "typeString": "literal_string \"Granularity can not be 0\"" + } + ], + "id": 21410, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "13192:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21415, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13192:54:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21416, + "nodeType": "ExpressionStatement", + "src": "13192:54:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21418, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "13283:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21419, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21405, + "src": "13296:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21417, + "name": "LogGranularityChanged", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20711, + "src": "13261:21:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 21420, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13261:48:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21421, + "nodeType": "EmitStatement", + "src": "13256:53:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21424, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21422, + "name": "granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10030, + "src": "13319:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 21423, + "name": "_granularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21405, + "src": "13333:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13319:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21425, + "nodeType": "ExpressionStatement", + "src": "13319:26:59" + } + ] + }, + "documentation": "@notice allows owner to change token granularity\n@param _granularity granularity level of the token", + "id": 21427, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21408, + "modifierName": { + "argumentTypes": null, + "id": 21407, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "13172:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "13172:9:59" + } + ], + "name": "changeGranularity", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21406, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21405, + "name": "_granularity", + "nodeType": "VariableDeclaration", + "scope": 21427, + "src": "13143:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21404, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13143:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13142:22:59" + }, + "payable": false, + "returnParameters": { + "id": 21409, + "nodeType": "ParameterList", + "parameters": [], + "src": "13182:0:59" + }, + "scope": 22534, + "src": "13116:236:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21509, + "nodeType": "Block", + "src": "13635:603:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21444, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21438, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21436, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21433, + "src": "13650:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21437, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13660:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13650:11:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21439, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13649:13:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21442, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21440, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21429, + "src": "13667:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 21441, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "13676:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13667:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21443, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13666:14:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13649:31:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21447, + "nodeType": "IfStatement", + "src": "13645:68:59", + "trueBody": { + "id": 21446, + "nodeType": "Block", + "src": "13682:31:59", + "statements": [ + { + "expression": null, + "functionReturnParameters": 21435, + "id": 21445, + "nodeType": "Return", + "src": "13696:7:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21460, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21452, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21449, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "13793:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21448, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "13783:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21450, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13783:14:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21451, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13801:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "13783:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21453, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13782:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21458, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21454, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "13808:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21456, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13823:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21455, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "13815:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21457, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13815:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "13808:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21459, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13807:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "13782:44:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21469, + "nodeType": "IfStatement", + "src": "13778:111:59", + "trueBody": { + "id": 21468, + "nodeType": "Block", + "src": "13828:61:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21466, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21461, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "13842:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 21464, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13876:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "expression": { + "argumentTypes": null, + "id": 21462, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "13858:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21463, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "13858:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21465, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13858:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13842:36:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21467, + "nodeType": "ExpressionStatement", + "src": "13842:36:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21474, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21470, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21433, + "src": "13964:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21472, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21429, + "src": "13984:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21471, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "13974:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21473, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "13974:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "13964:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21483, + "nodeType": "IfStatement", + "src": "13960:93:59", + "trueBody": { + "id": 21482, + "nodeType": "Block", + "src": "13992:61:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21480, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21475, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "14006:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 21478, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14040:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "expression": { + "argumentTypes": null, + "id": 21476, + "name": "investorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10034, + "src": "14022:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21477, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "14022:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21479, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14022:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14006:36:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21481, + "nodeType": "ExpressionStatement", + "src": "14006:36:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21494, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21487, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "14102:20:59", + "subExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21484, + "name": "investorListed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20683, + "src": "14103:14:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + } + }, + "id": 21486, + "indexExpression": { + "argumentTypes": null, + "id": 21485, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14118:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14103:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21492, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21488, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14127:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21490, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14142:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21489, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "14134:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21491, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14134:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "14127:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21493, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14126:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "14102:43:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21508, + "nodeType": "IfStatement", + "src": "14098:133:59", + "trueBody": { + "id": 21507, + "nodeType": "Block", + "src": "14147:84:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21498, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14176:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "argumentTypes": null, + "id": 21495, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14161:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21497, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14161:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) returns (uint256)" + } + }, + "id": 21499, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14161:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21500, + "nodeType": "ExpressionStatement", + "src": "14161:19:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21505, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21501, + "name": "investorListed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20683, + "src": "14194:14:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + } + }, + "id": 21503, + "indexExpression": { + "argumentTypes": null, + "id": 21502, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21431, + "src": "14209:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "14194:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21504, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14216:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "14194:26:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21506, + "nodeType": "ExpressionStatement", + "src": "14194:26:59" + } + ] + } + } + ] + }, + "documentation": "@notice keeps track of the number of non-zero token holders\n@param _from sender of transfer\n@param _to receiver of transfer\n@param _value value of transfer", + "id": 21510, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustInvestorCount", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21434, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21429, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 21510, + "src": "13582:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21428, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13582:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21431, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21510, + "src": "13597:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21430, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13597:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21433, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 21510, + "src": "13610:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21432, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13610:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "13581:44:59" + }, + "payable": false, + "returnParameters": { + "id": 21435, + "nodeType": "ParameterList", + "parameters": [], + "src": "13635:0:59" + }, + "scope": 22534, + "src": "13553:685:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21579, + "nodeType": "Block", + "src": "14676:356:59", + "statements": [ + { + "body": { + "id": 21577, + "nodeType": "Block", + "src": "14771:255:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 21550, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21540, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21537, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14790:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21538, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14794:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21539, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14794:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14790:20:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21541, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14789:22:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21548, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21543, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14826:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21545, + "indexExpression": { + "argumentTypes": null, + "id": 21544, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14836:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14826:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21542, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "14816:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21546, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14816:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21547, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14843:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "14816:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21549, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14815:30:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "14789:56:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21576, + "nodeType": "IfStatement", + "src": "14785:231:59", + "trueBody": { + "id": 21575, + "nodeType": "Block", + "src": "14847:169:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21557, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21551, + "name": "investorListed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20683, + "src": "14865:14:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + } + }, + "id": 21555, + "indexExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21552, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14880:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21554, + "indexExpression": { + "argumentTypes": null, + "id": 21553, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14890:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14880:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "14865:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21556, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14896:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "14865:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21558, + "nodeType": "ExpressionStatement", + "src": "14865:36:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21568, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21559, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14919:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21561, + "indexExpression": { + "argumentTypes": null, + "id": 21560, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14929:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "14919:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21562, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14934:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21567, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21566, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21563, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14944:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21564, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14944:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21565, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14963:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "14944:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "14934:31:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "14919:46:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 21569, + "nodeType": "ExpressionStatement", + "src": "14919:46:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21573, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "--", + "prefix": false, + "src": "14983:18:59", + "subExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21570, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14983:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21572, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14983:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21574, + "nodeType": "ExpressionStatement", + "src": "14983:18:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21533, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21523, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14711:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21528, + "name": "_iters", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21514, + "src": "14738:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21526, + "name": "_start", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21512, + "src": "14727:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21527, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "14727:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21529, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14727:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21530, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "14747:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21531, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "14747:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21524, + "name": "Math", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22661, + "src": "14715:4:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Math_$22661_$", + "typeString": "type(library Math)" + } + }, + "id": 21525, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "min256", + "nodeType": "MemberAccess", + "referencedDeclaration": 22660, + "src": "14715:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 21532, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "14715:49:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "14711:53:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21578, + "initializationExpression": { + "assignments": [ + 21520 + ], + "declarations": [ + { + "constant": false, + "id": 21520, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 21580, + "src": "14691:9:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21519, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14691:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21522, + "initialValue": { + "argumentTypes": null, + "id": 21521, + "name": "_start", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21512, + "src": "14703:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "14691:18:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 21535, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "14766:3:59", + "subExpression": { + "argumentTypes": null, + "id": 21534, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21520, + "src": "14766:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21536, + "nodeType": "ExpressionStatement", + "src": "14766:3:59" + }, + "nodeType": "ForStatement", + "src": "14686:340:59" + } + ] + }, + "documentation": "@notice removes addresses with zero balances from the investors list\n@param _start Index in investor list at which to start removing zero balances\n@param _iters Max number of iterations of the for loop\nNB - pruning this list will mean you may not be able to iterate over investors on-chain as of a historical checkpoint", + "id": 21580, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21517, + "modifierName": { + "argumentTypes": null, + "id": 21516, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "14666:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "14666:9:59" + } + ], + "name": "pruneInvestors", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21515, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21512, + "name": "_start", + "nodeType": "VariableDeclaration", + "scope": 21580, + "src": "14627:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21511, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14627:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21514, + "name": "_iters", + "nodeType": "VariableDeclaration", + "scope": 21580, + "src": "14643:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21513, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "14643:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "14626:32:59" + }, + "payable": false, + "returnParameters": { + "id": 21518, + "nodeType": "ParameterList", + "parameters": [], + "src": "14676:0:59" + }, + "scope": 22534, + "src": "14603:429:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21588, + "nodeType": "Block", + "src": "15289:40:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21585, + "name": "investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10037, + "src": "15306:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage", + "typeString": "address[] storage ref" + } + }, + "id": 21586, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "15306:16:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 21584, + "id": 21587, + "nodeType": "Return", + "src": "15299:23:59" + } + ] + }, + "documentation": "@notice gets length of investors array\nNB - this length may differ from investorCount if list has not been pruned of zero balance investors\n@return length", + "id": 21589, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getInvestorsLength", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21581, + "nodeType": "ParameterList", + "parameters": [], + "src": "15257:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21584, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21583, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21589, + "src": "15280:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21582, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "15280:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "15279:9:59" + }, + "scope": 22534, + "src": "15230:99:59", + "stateMutability": "view", + "superFunction": 10096, + "visibility": "public" + }, + { + "body": { + "id": 21608, + "nodeType": "Block", + "src": "15435:102:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21596, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "15453:7:59", + "subExpression": { + "argumentTypes": null, + "id": 21595, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15454:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21594, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "15445:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21597, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15445:16:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21598, + "nodeType": "ExpressionStatement", + "src": "15445:16:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21601, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21599, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15471:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21600, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15480:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "15471:13:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21602, + "nodeType": "ExpressionStatement", + "src": "15471:13:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21604, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15518:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "id": 21605, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "15526:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21603, + "name": "LogFreezeTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20733, + "src": "15499:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$_t_uint256_$returns$__$", + "typeString": "function (bool,uint256)" + } + }, + "id": 21606, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15499:31:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21607, + "nodeType": "EmitStatement", + "src": "15494:36:59" + } + ] + }, + "documentation": "@notice freeze all the transfers", + "id": 21609, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21592, + "modifierName": { + "argumentTypes": null, + "id": 21591, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "15425:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "15425:9:59" + } + ], + "name": "freezeTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21590, + "nodeType": "ParameterList", + "parameters": [], + "src": "15415:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21593, + "nodeType": "ParameterList", + "parameters": [], + "src": "15435:0:59" + }, + "scope": 22534, + "src": "15391:146:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21627, + "nodeType": "Block", + "src": "15648:102:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21615, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15666:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21614, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "15658:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21616, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15658:15:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21617, + "nodeType": "ExpressionStatement", + "src": "15658:15:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 21620, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21618, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15683:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21619, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "15692:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "15683:14:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21621, + "nodeType": "ExpressionStatement", + "src": "15683:14:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21623, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "15731:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "id": 21624, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "15739:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21622, + "name": "LogFreezeTransfers", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20733, + "src": "15712:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bool_$_t_uint256_$returns$__$", + "typeString": "function (bool,uint256)" + } + }, + "id": 21625, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15712:31:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21626, + "nodeType": "EmitStatement", + "src": "15707:36:59" + } + ] + }, + "documentation": "@notice un-freeze all the transfers", + "id": 21628, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21612, + "modifierName": { + "argumentTypes": null, + "id": 21611, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "15638:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "15638:9:59" + } + ], + "name": "unfreezeTransfers", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21610, + "nodeType": "ParameterList", + "parameters": [], + "src": "15628:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21613, + "nodeType": "ParameterList", + "parameters": [], + "src": "15648:0:59" + }, + "scope": 22534, + "src": "15602:148:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21637, + "nodeType": "Block", + "src": "15901:72:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21632, + "name": "checkpointTotalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20661, + "src": "15929:21:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 21633, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22864 + ], + "referencedDeclaration": 22864, + "src": "15952:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 21634, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15952:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21631, + "name": "adjustCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21705, + "src": "15911:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$returns$__$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256)" + } + }, + "id": 21635, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "15911:55:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21636, + "nodeType": "ExpressionStatement", + "src": "15911:55:59" + } + ] + }, + "documentation": "@notice adjust totalsupply at checkpoint after minting or burning tokens", + "id": 21638, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustTotalSupplyCheckpoints", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21629, + "nodeType": "ParameterList", + "parameters": [], + "src": "15889:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21630, + "nodeType": "ParameterList", + "parameters": [], + "src": "15901:0:59" + }, + "scope": 22534, + "src": "15852:121:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21652, + "nodeType": "Block", + "src": "16198:87:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21644, + "name": "checkpointBalances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20658, + "src": "16226:18:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint storage ref[] storage ref)" + } + }, + "id": 21646, + "indexExpression": { + "argumentTypes": null, + "id": 21645, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21640, + "src": "16245:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "16226:29:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21648, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21640, + "src": "16267:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21647, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "16257:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 21649, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16257:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21643, + "name": "adjustCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21705, + "src": "16208:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$returns$__$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256)" + } + }, + "id": 21650, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16208:70:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21651, + "nodeType": "ExpressionStatement", + "src": "16208:70:59" + } + ] + }, + "documentation": "@notice adjust token holder balance at checkpoint after a token transfer\n@param _investor address of the token holder affected", + "id": 21653, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustBalanceCheckpoints", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21641, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21640, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 21653, + "src": "16170:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21639, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "16170:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "16169:19:59" + }, + "payable": false, + "returnParameters": { + "id": 21642, + "nodeType": "ParameterList", + "parameters": [], + "src": "16198:0:59" + }, + "scope": 22534, + "src": "16136:149:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21704, + "nodeType": "Block", + "src": "16582:817:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21663, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21661, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "16629:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21662, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16652:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "16629:24:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21666, + "nodeType": "IfStatement", + "src": "16625:61:59", + "trueBody": { + "id": 21665, + "nodeType": "Block", + "src": "16655:31:59", + "statements": [ + { + "expression": null, + "functionReturnParameters": 21660, + "id": 21664, + "nodeType": "Return", + "src": "16669:7:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21670, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21667, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "16778:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21668, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16778:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21669, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "16801:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "16778:24:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21682, + "nodeType": "IfStatement", + "src": "16774:247:59", + "trueBody": { + "id": 21681, + "nodeType": "Block", + "src": "16804:217:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21675, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "16900:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21676, + "name": "_newValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21658, + "src": "16948:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": null, + "id": 21674, + "name": "Checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20653, + "src": "16853:10:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_Checkpoint_$20653_storage_ptr_$", + "typeString": "type(struct SecurityToken.Checkpoint storage pointer)" + } + }, + "id": 21677, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [ + "checkpointId", + "value" + ], + "nodeType": "FunctionCall", + "src": "16853:123:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 21671, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "16818:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21673, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "16818:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_struct$_Checkpoint_$20653_storage_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref) returns (uint256)" + } + }, + "id": 21678, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "16818:172:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21679, + "nodeType": "ExpressionStatement", + "src": "16818:172:59" + }, + { + "expression": null, + "functionReturnParameters": 21660, + "id": 21680, + "nodeType": "Return", + "src": "17004:7:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21691, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21683, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "17081:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21688, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21687, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21684, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "17094:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21685, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17094:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 21686, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17116:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "17094:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "17081:37:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 21689, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "17081:50:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 21690, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "17135:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "17081:73:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21694, + "nodeType": "IfStatement", + "src": "17077:110:59", + "trueBody": { + "id": 21693, + "nodeType": "Block", + "src": "17156:31:59", + "statements": [ + { + "expression": null, + "functionReturnParameters": 21660, + "id": 21692, + "nodeType": "Return", + "src": "17170:7:59" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21699, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "17314:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21700, + "name": "_newValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21658, + "src": "17358:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": null, + "id": 21698, + "name": "Checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20653, + "src": "17271:10:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_Checkpoint_$20653_storage_ptr_$", + "typeString": "type(struct SecurityToken.Checkpoint storage pointer)" + } + }, + "id": 21701, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "structConstructorCall", + "lValueRequested": false, + "names": [ + "checkpointId", + "value" + ], + "nodeType": "FunctionCall", + "src": "17271:111:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_Checkpoint_$20653_memory", + "typeString": "struct SecurityToken.Checkpoint memory" + } + ], + "expression": { + "argumentTypes": null, + "id": 21695, + "name": "_checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21656, + "src": "17240:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 21697, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "push", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17240:17:59", + "typeDescriptions": { + "typeIdentifier": "t_function_arraypush_nonpayable$_t_struct$_Checkpoint_$20653_storage_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref) returns (uint256)" + } + }, + "id": 21702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17240:152:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21703, + "nodeType": "ExpressionStatement", + "src": "17240:152:59" + } + ] + }, + "documentation": "@notice store the changes to the checkpoint objects\n@param _checkpoints the affected checkpoint object array\n@param _newValue the new value that needs to be stored", + "id": 21705, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "adjustCheckpoints", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21659, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21656, + "name": "_checkpoints", + "nodeType": "VariableDeclaration", + "scope": 21705, + "src": "16519:33:59", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + }, + "typeName": { + "baseType": { + "contractScope": null, + "id": 21654, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "16519:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 21655, + "length": null, + "nodeType": "ArrayTypeName", + "src": "16519:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21658, + "name": "_newValue", + "nodeType": "VariableDeclaration", + "scope": 21705, + "src": "16554:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21657, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "16554:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "16518:54:59" + }, + "payable": false, + "returnParameters": { + "id": 21660, + "nodeType": "ParameterList", + "parameters": [], + "src": "16582:0:59" + }, + "scope": 22534, + "src": "16492:907:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 21750, + "nodeType": "Block", + "src": "17663:296:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21715, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "17693:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21716, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17693:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21717, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17705:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21718, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21709, + "src": "17710:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21714, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "17673:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 21719, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17673:44:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21720, + "nodeType": "ExpressionStatement", + "src": "17673:44:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21723, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "17750:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17750:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21725, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17762:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21726, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21709, + "src": "17767:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21722, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "17735:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 21727, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17735:39:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 21728, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17776:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 21721, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "17727:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21729, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17727:73:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21730, + "nodeType": "ExpressionStatement", + "src": "17727:73:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21732, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "17835:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21733, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "17835:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21731, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "17810:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21734, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17810:36:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21735, + "nodeType": "ExpressionStatement", + "src": "17810:36:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21737, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17881:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21736, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "17856:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21738, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17856:29:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21739, + "nodeType": "ExpressionStatement", + "src": "17856:29:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21743, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21707, + "src": "17918:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21744, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21709, + "src": "17923:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21741, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23374, + "src": "17903:5:59", + "typeDescriptions": { + "typeIdentifier": "t_super$_SecurityToken_$22534", + "typeString": "contract super SecurityToken" + } + }, + "id": 21742, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "transfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 22924, + "src": "17903:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) returns (bool)" + } + }, + "id": 21745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17903:27:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21740, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "17895:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21746, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "17895:36:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21747, + "nodeType": "ExpressionStatement", + "src": "17895:36:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21748, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "17948:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21713, + "id": 21749, + "nodeType": "Return", + "src": "17941:11:59" + } + ] + }, + "documentation": "@notice Overloaded version of the transfer function\n@param _to receiver of transfer\n@param _value value of transfer\n@return bool success", + "id": 21751, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "transfer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21710, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21707, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21751, + "src": "17604:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21706, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "17604:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21709, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 21751, + "src": "17617:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21708, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "17617:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "17603:29:59" + }, + "payable": false, + "returnParameters": { + "id": 21713, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21712, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 21751, + "src": "17649:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21711, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "17649:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "17648:14:59" + }, + "scope": 22534, + "src": "17586:373:59", + "stateMutability": "nonpayable", + "superFunction": 22924, + "visibility": "public" + }, + { + "body": { + "id": 21796, + "nodeType": "Block", + "src": "18285:292:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21763, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18315:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21764, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18322:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21765, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21757, + "src": "18327:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21762, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "18295:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 21766, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18295:39:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21767, + "nodeType": "ExpressionStatement", + "src": "18295:39:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21770, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18367:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21771, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18374:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21772, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21757, + "src": "18379:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21769, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "18352:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 21773, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18352:34:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 21774, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18388:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 21768, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "18344:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21775, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18344:68:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21776, + "nodeType": "ExpressionStatement", + "src": "18344:68:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21778, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18447:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21777, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "18422:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21779, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18422:31:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21780, + "nodeType": "ExpressionStatement", + "src": "18422:31:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21782, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18488:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21781, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "18463:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 21783, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18463:29:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21784, + "nodeType": "ExpressionStatement", + "src": "18463:29:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21788, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21753, + "src": "18529:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21789, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21755, + "src": "18536:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21790, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21757, + "src": "18541:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 21786, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23374, + "src": "18510:5:59", + "typeDescriptions": { + "typeIdentifier": "t_super$_SecurityToken_$22534", + "typeString": "contract super SecurityToken" + } + }, + "id": 21787, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "transferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 23146, + "src": "18510:18:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 21791, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18510:38:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 21785, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "18502:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 21792, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "18502:47:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21793, + "nodeType": "ExpressionStatement", + "src": "18502:47:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21794, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "18566:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21761, + "id": 21795, + "nodeType": "Return", + "src": "18559:11:59" + } + ] + }, + "documentation": "@notice Overloaded version of the transferFrom function\n@param _from sender of transfer\n@param _to receiver of transfer\n@param _value value of transfer\n@return bool success", + "id": 21797, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "transferFrom", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21758, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21753, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18211:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21752, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18211:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21755, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18226:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21754, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18226:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21757, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18239:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21756, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18239:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18210:44:59" + }, + "payable": false, + "returnParameters": { + "id": 21761, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21760, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 21797, + "src": "18271:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21759, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "18271:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18270:14:59" + }, + "scope": 22534, + "src": "18189:388:59", + "stateMutability": "nonpayable", + "superFunction": 23146, + "visibility": "public" + }, + { + "body": { + "id": 21931, + "nodeType": "Block", + "src": "18978:1097:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "id": 21812, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "18992:7:59", + "subExpression": { + "argumentTypes": null, + "id": 21811, + "name": "freeze", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20643, + "src": "18993:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21928, + "nodeType": "IfStatement", + "src": "18988:1061:59", + "trueBody": { + "id": 21927, + "nodeType": "Block", + "src": "19001:1048:59", + "statements": [ + { + "assignments": [ + 21814 + ], + "declarations": [ + { + "constant": false, + "id": 21814, + "name": "isTransfer", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19015:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21813, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19015:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21816, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21815, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19033:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19015:23:59" + }, + { + "condition": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21817, + "name": "transferFunctions", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20671, + "src": "19056:17:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_bytes4_$_t_bool_$", + "typeString": "mapping(bytes4 => bool)" + } + }, + "id": 21822, + "indexExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21819, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "19081:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 21820, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19081:8:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 21818, + "name": "getSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22324, + "src": "19074:6:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_memory_ptr_$returns$_t_bytes4_$", + "typeString": "function (bytes memory) pure returns (bytes4)" + } + }, + "id": 21821, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19074:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19056:35:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21828, + "nodeType": "IfStatement", + "src": "19052:89:59", + "trueBody": { + "id": 21827, + "nodeType": "Block", + "src": "19093:48:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21825, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21823, + "name": "isTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21814, + "src": "19109:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21824, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19122:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19109:17:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21826, + "nodeType": "ExpressionStatement", + "src": "19109:17:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21834, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21829, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "19158:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21831, + "indexExpression": { + "argumentTypes": null, + "id": 21830, + "name": "TRANSFERMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10022, + "src": "19166:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19158:28:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21832, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19158:35:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 21833, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19197:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "19158:40:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21838, + "nodeType": "IfStatement", + "src": "19154:90:59", + "trueBody": { + "id": 21837, + "nodeType": "Block", + "src": "19200:44:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21835, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19225:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21810, + "id": 21836, + "nodeType": "Return", + "src": "19218:11:59" + } + ] + } + }, + { + "assignments": [ + 21840 + ], + "declarations": [ + { + "constant": false, + "id": 21840, + "name": "isInvalid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19257:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21839, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19257:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21842, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21841, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19274:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19257:22:59" + }, + { + "assignments": [ + 21844 + ], + "declarations": [ + { + "constant": false, + "id": 21844, + "name": "isValid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19293:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21843, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19293:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21846, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21845, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19308:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19293:20:59" + }, + { + "assignments": [ + 21848 + ], + "declarations": [ + { + "constant": false, + "id": 21848, + "name": "isForceValid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19327:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21847, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "19327:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21850, + "initialValue": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21849, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19347:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19327:25:59" + }, + { + "body": { + "id": 21916, + "nodeType": "Block", + "src": "19430:539:59", + "statements": [ + { + "assignments": [ + 21867 + ], + "declarations": [ + { + "constant": false, + "id": 21867, + "name": "valid", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19448:29:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "typeName": { + "contractScope": null, + "id": 21866, + "name": "ITransferManager.Result", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 18484, + "src": "19448:23:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21882, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21877, + "name": "_from", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21799, + "src": "19559:5:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21878, + "name": "_to", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21801, + "src": "19566:3:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21879, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21803, + "src": "19571:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 21880, + "name": "isTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21814, + "src": "19580:10:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21869, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "19497:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21871, + "indexExpression": { + "argumentTypes": null, + "id": 21870, + "name": "TRANSFERMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10022, + "src": "19505:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19497:28:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21873, + "indexExpression": { + "argumentTypes": null, + "id": 21872, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21852, + "src": "19526:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19497:31:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 21874, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "19497:45:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 21868, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19480:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21875, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19480:63:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITransferManager_$18520", + "typeString": "contract ITransferManager" + } + }, + "id": 21876, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "verifyTransfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 18497, + "src": "19480:78:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bool_$returns$_t_enum$_Result_$18484_$", + "typeString": "function (address,address,uint256,bool) external returns (enum ITransferManager.Result)" + } + }, + "id": 21881, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "19480:111:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "19448:143:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "id": 21887, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21883, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21867, + "src": "19613:5:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21884, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19622:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21885, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "Result", + "nodeType": "MemberAccess", + "referencedDeclaration": 18484, + "src": "19622:23:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18484_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 21886, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "INVALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19622:31:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "src": "19613:40:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21893, + "nodeType": "IfStatement", + "src": "19609:103:59", + "trueBody": { + "id": 21892, + "nodeType": "Block", + "src": "19655:57:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21888, + "name": "isInvalid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21840, + "src": "19677:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21889, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19689:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19677:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21891, + "nodeType": "ExpressionStatement", + "src": "19677:16:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "id": 21898, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21894, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21867, + "src": "19733:5:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21895, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19742:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21896, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "Result", + "nodeType": "MemberAccess", + "referencedDeclaration": 18484, + "src": "19742:23:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18484_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 21897, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19742:29:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "src": "19733:38:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21904, + "nodeType": "IfStatement", + "src": "19729:99:59", + "trueBody": { + "id": 21903, + "nodeType": "Block", + "src": "19773:55:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21901, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21899, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21844, + "src": "19795:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21900, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19805:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19795:14:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21902, + "nodeType": "ExpressionStatement", + "src": "19795:14:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + }, + "id": 21909, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21905, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21867, + "src": "19849:5:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 21906, + "name": "ITransferManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 18520, + "src": "19858:16:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITransferManager_$18520_$", + "typeString": "type(contract ITransferManager)" + } + }, + "id": 21907, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "Result", + "nodeType": "MemberAccess", + "referencedDeclaration": 18484, + "src": "19858:23:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_enum$_Result_$18484_$", + "typeString": "type(enum ITransferManager.Result)" + } + }, + "id": 21908, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "FORCE_VALID", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19858:35:59", + "typeDescriptions": { + "typeIdentifier": "t_enum$_Result_$18484", + "typeString": "enum ITransferManager.Result" + } + }, + "src": "19849:44:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 21915, + "nodeType": "IfStatement", + "src": "19845:110:59", + "trueBody": { + "id": 21914, + "nodeType": "Block", + "src": "19895:60:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21912, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21910, + "name": "isForceValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21848, + "src": "19917:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21911, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19932:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "19917:19:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21913, + "nodeType": "ExpressionStatement", + "src": "19917:19:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 21860, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21855, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21852, + "src": "19384:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 21856, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "19388:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 21858, + "indexExpression": { + "argumentTypes": null, + "id": 21857, + "name": "TRANSFERMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10022, + "src": "19396:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "19388:28:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 21859, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "19388:35:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "19384:39:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21917, + "initializationExpression": { + "assignments": [ + 21852 + ], + "declarations": [ + { + "constant": false, + "id": 21852, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "19371:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 21851, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "19371:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 21854, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 21853, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "19381:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "19371:11:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 21862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "19425:3:59", + "subExpression": { + "argumentTypes": null, + "id": 21861, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21852, + "src": "19425:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 21863, + "nodeType": "ExpressionStatement", + "src": "19425:3:59" + }, + "nodeType": "ForStatement", + "src": "19366:603:59" + }, + { + "expression": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "id": 21918, + "name": "isForceValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21848, + "src": "19989:12:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "id": 21920, + "name": "isInvalid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21840, + "src": "20012:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "id": 21922, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21844, + "src": "20032:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21923, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "20012:27:59", + "trueExpression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21921, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20024:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "id": 21924, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "20011:29:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21925, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "19989:51:59", + "trueExpression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21919, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20004:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 21810, + "id": 21926, + "nodeType": "Return", + "src": "19982:58:59" + } + ] + } + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 21929, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20063:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 21810, + "id": 21930, + "nodeType": "Return", + "src": "20056:12:59" + } + ] + }, + "documentation": "@notice validate transfer with TransferManager module if it exists\n@dev TransferManager module has a key of 2\n@param _from sender of transfer\n@param _to receiver of transfer\n@param _amount value of transfer\n@return bool", + "id": 21932, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 21806, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21803, + "src": "18954:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 21807, + "modifierName": { + "argumentTypes": null, + "id": 21805, + "name": "checkGranularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20849, + "src": "18937:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "18937:25:59" + } + ], + "name": "verifyTransfer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21804, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21799, + "name": "_from", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18885:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21798, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18885:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21801, + "name": "_to", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18900:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21800, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18900:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21803, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18913:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21802, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "18913:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18884:45:59" + }, + "payable": false, + "returnParameters": { + "id": 21810, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21809, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 21932, + "src": "18972:4:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21808, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "18972:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "18971:6:59" + }, + "scope": 22534, + "src": "18861:1214:59", + "stateMutability": "nonpayable", + "superFunction": 9959, + "visibility": "public" + }, + { + "body": { + "id": 21945, + "nodeType": "Block", + "src": "20208:87:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21939, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21937, + "name": "finishedIssuerMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20664, + "src": "20218:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21938, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20242:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "20218:28:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21940, + "nodeType": "ExpressionStatement", + "src": "20218:28:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21942, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "20284:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21941, + "name": "LogFinishMintingIssuer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20743, + "src": "20261:22:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256)" + } + }, + "id": 21943, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20261:27:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21944, + "nodeType": "EmitStatement", + "src": "20256:32:59" + } + ] + }, + "documentation": "@notice End token minting period permanently for Issuer", + "id": 21946, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21935, + "modifierName": { + "argumentTypes": null, + "id": 21934, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "20198:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "20198:9:59" + } + ], + "name": "finishMintingIssuer", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21933, + "nodeType": "ParameterList", + "parameters": [], + "src": "20188:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21936, + "nodeType": "ParameterList", + "parameters": [], + "src": "20208:0:59" + }, + "scope": 22534, + "src": "20160:135:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 21959, + "nodeType": "Block", + "src": "20423:81:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 21953, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 21951, + "name": "finishedSTOMinting", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20667, + "src": "20433:18:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21952, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20454:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "src": "20433:25:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 21954, + "nodeType": "ExpressionStatement", + "src": "20433:25:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 21956, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "20493:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21955, + "name": "LogFinishMintingSTO", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20747, + "src": "20473:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256)" + } + }, + "id": 21957, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "20473:24:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21958, + "nodeType": "EmitStatement", + "src": "20468:29:59" + } + ] + }, + "documentation": "@notice End token minting period permanently for STOs", + "id": 21960, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 21949, + "modifierName": { + "argumentTypes": null, + "id": 21948, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "20413:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "20413:9:59" + } + ], + "name": "finishMintingSTO", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21947, + "nodeType": "ParameterList", + "parameters": [], + "src": "20403:2:59" + }, + "payable": false, + "returnParameters": { + "id": 21950, + "nodeType": "ParameterList", + "parameters": [], + "src": "20423:0:59" + }, + "scope": 22534, + "src": "20378:126:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 22046, + "nodeType": "Block", + "src": "21016:553:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 21983, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 21979, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21034:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21981, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21055:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21980, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21047:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21982, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21047:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "21034:23:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "496e766573746f7220616464726573732073686f756c64206e6f74206265203078", + "id": 21984, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21059:35:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_92c9ad5839d9e6c845f0585522dbe71544d58a6d51db03cf580afd2032f01f8c", + "typeString": "literal_string \"Investor address should not be 0x\"" + }, + "value": "Investor address should not be 0x" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_92c9ad5839d9e6c845f0585522dbe71544d58a6d51db03cf580afd2032f01f8c", + "typeString": "literal_string \"Investor address should not be 0x\"" + } + ], + "id": 21978, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "21026:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 21985, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21026:69:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21986, + "nodeType": "ExpressionStatement", + "src": "21026:69:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21989, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21133:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21988, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21125:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21990, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21125:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21991, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21137:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 21992, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21148:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21987, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "21105:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 21993, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21105:51:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 21994, + "nodeType": "ExpressionStatement", + "src": "21105:51:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 21998, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21197:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 21997, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21189:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 21999, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21189:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22000, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21201:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22001, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21212:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 21996, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "21174:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 22002, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21174:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 22003, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21222:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 21995, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "21166:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21166:80:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22005, + "nodeType": "ExpressionStatement", + "src": "21166:80:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22007, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21281:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22006, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "21256:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 22008, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21256:35:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22009, + "nodeType": "ExpressionStatement", + "src": "21256:35:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 22010, + "name": "adjustTotalSupplyCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21638, + "src": "21301:28:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 22011, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21301:30:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22012, + "nodeType": "ExpressionStatement", + "src": "21301:30:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22018, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22013, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "21341:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22016, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21373:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 22014, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "21356:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22015, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "21356:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22017, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21356:25:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "21341:40:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22019, + "nodeType": "ExpressionStatement", + "src": "21341:40:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22029, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22020, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "21391:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22022, + "indexExpression": { + "argumentTypes": null, + "id": 22021, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21400:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "21391:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22027, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21437:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22023, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "21413:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22025, + "indexExpression": { + "argumentTypes": null, + "id": 22024, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21422:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "21413:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22026, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "add", + "nodeType": "MemberAccess", + "referencedDeclaration": 22754, + "src": "21413:23:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22028, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21413:32:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "21391:54:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22030, + "nodeType": "ExpressionStatement", + "src": "21391:54:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22032, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21467:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22033, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21478:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22031, + "name": "Minted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9979, + "src": "21460:6:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 22034, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21460:26:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22035, + "nodeType": "EmitStatement", + "src": "21455:31:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22038, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21518:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22037, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "21510:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22039, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21510:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22040, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21962, + "src": "21522:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22041, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "21533:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22036, + "name": "Transfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23045, + "src": "21501:8:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 22042, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "21501:40:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22043, + "nodeType": "EmitStatement", + "src": "21496:45:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22044, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "21558:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 21977, + "id": 22045, + "nodeType": "Return", + "src": "21551:11:59" + } + ] + }, + "documentation": "@notice mints new tokens and assigns them to the target _investor.\n@dev Can only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet)\n@param _investor Address to whom the minted tokens will be dilivered\n@param _amount Number of tokens get minted\n@return success", + "id": 22047, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 21967, + "name": "STO_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10025, + "src": "20933:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 21968, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "20942:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "id": 21969, + "modifierName": { + "argumentTypes": null, + "id": 21966, + "name": "onlyModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20834, + "src": "20922:10:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint8_$_t_bool_$", + "typeString": "modifier (uint8,bool)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20922:25:59" + }, + { + "arguments": [ + { + "argumentTypes": null, + "id": 21971, + "name": "_amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21964, + "src": "20965:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 21972, + "modifierName": { + "argumentTypes": null, + "id": 21970, + "name": "checkGranularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20849, + "src": "20948:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "20948:25:59" + }, + { + "arguments": [], + "id": 21974, + "modifierName": { + "argumentTypes": null, + "id": 21973, + "name": "isMintingAllowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20872, + "src": "20974:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "20974:18:59" + } + ], + "name": "mint", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 21965, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21962, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 22047, + "src": "20879:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 21961, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "20879:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 21964, + "name": "_amount", + "nodeType": "VariableDeclaration", + "scope": 22047, + "src": "20898:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 21963, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "20898:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "20878:36:59" + }, + "payable": false, + "returnParameters": { + "id": 21977, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21976, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 22047, + "src": "21002:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 21975, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "21002:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "21001:14:59" + }, + "scope": 22534, + "src": "20865:704:59", + "stateMutability": "nonpayable", + "superFunction": 9968, + "visibility": "public" + }, + { + "body": { + "id": 22095, + "nodeType": "Block", + "src": "22142:238:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22067, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22063, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22050, + "src": "22160:10:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 22064, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22160:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22065, + "name": "_amounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22053, + "src": "22181:8:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 22066, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22181:15:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "22160:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "4d69732d6d6174636820696e20746865206c656e677468206f662074686520617272617973", + "id": 22068, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22198:39:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_e6e9985f4f54b573f3a5eba669f45bb98ec50cd60909ea443be6588371310a0e", + "typeString": "literal_string \"Mis-match in the length of the arrays\"" + }, + "value": "Mis-match in the length of the arrays" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_e6e9985f4f54b573f3a5eba669f45bb98ec50cd60909ea443be6588371310a0e", + "typeString": "literal_string \"Mis-match in the length of the arrays\"" + } + ], + "id": 22062, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "22152:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22069, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22152:86:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22070, + "nodeType": "ExpressionStatement", + "src": "22152:86:59" + }, + { + "body": { + "id": 22091, + "nodeType": "Block", + "src": "22296:57:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22083, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22050, + "src": "22315:10:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 22085, + "indexExpression": { + "argumentTypes": null, + "id": 22084, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22326:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22315:13:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22086, + "name": "_amounts", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22053, + "src": "22330:8:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[] memory" + } + }, + "id": 22088, + "indexExpression": { + "argumentTypes": null, + "id": 22087, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22339:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22330:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22082, + "name": "mint", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22047 + ], + "referencedDeclaration": 22047, + "src": "22310:4:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) returns (bool)" + } + }, + "id": 22089, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "22310:32:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22090, + "nodeType": "ExpressionStatement", + "src": "22310:32:59" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22078, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22075, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22268:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22076, + "name": "_investors", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22050, + "src": "22272:10:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[] memory" + } + }, + "id": 22077, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22272:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "22268:21:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22092, + "initializationExpression": { + "assignments": [ + 22072 + ], + "declarations": [ + { + "constant": false, + "id": 22072, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22253:9:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22071, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "22253:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22074, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22073, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22265:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "22253:13:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 22080, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "22291:3:59", + "subExpression": { + "argumentTypes": null, + "id": 22079, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22072, + "src": "22291:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22081, + "nodeType": "ExpressionStatement", + "src": "22291:3:59" + }, + "nodeType": "ForStatement", + "src": "22248:105:59" + }, + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22093, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22369:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 22061, + "id": 22094, + "nodeType": "Return", + "src": "22362:11:59" + } + ] + }, + "documentation": "@notice mints new tokens and assigns them to the target _investor.\nCan only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet)\n@param _investors A list of addresses to whom the minted tokens will be dilivered\n@param _amounts A list of number of tokens get minted and transfer to corresponding address of the investor from _investor[] list\n@return success", + "id": 22096, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 22056, + "name": "STO_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10025, + "src": "22104:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22057, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "22113:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "id": 22058, + "modifierName": { + "argumentTypes": null, + "id": 22055, + "name": "onlyModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20834, + "src": "22093:10:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint8_$_t_bool_$", + "typeString": "modifier (uint8,bool)" + } + }, + "nodeType": "ModifierInvocation", + "src": "22093:25:59" + } + ], + "name": "mintMulti", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22054, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22050, + "name": "_investors", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22044:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_memory_ptr", + "typeString": "address[]" + }, + "typeName": { + "baseType": { + "id": 22048, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22044:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 22049, + "length": null, + "nodeType": "ArrayTypeName", + "src": "22044:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_address_$dyn_storage_ptr", + "typeString": "address[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22053, + "name": "_amounts", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22066:18:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": { + "baseType": { + "id": 22051, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "22066:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22052, + "length": null, + "nodeType": "ArrayTypeName", + "src": "22066:9:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22043:42:59" + }, + "payable": false, + "returnParameters": { + "id": 22061, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22060, + "name": "success", + "nodeType": "VariableDeclaration", + "scope": 22096, + "src": "22128:12:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 22059, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "22128:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22127:14:59" + }, + "scope": 22534, + "src": "22025:355:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 22149, + "nodeType": "Block", + "src": "22966:361:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22112, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22107, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "22980:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 22109, + "indexExpression": { + "argumentTypes": null, + "id": 22108, + "name": "PERMISSIONMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10019, + "src": "22988:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "22980:30:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 22110, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "22980:37:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22111, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23021:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "22980:42:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22116, + "nodeType": "IfStatement", + "src": "22976:85:59", + "trueBody": { + "id": 22115, + "nodeType": "Block", + "src": "23024:37:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "66616c7365", + "id": 22113, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23045:5:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 22106, + "id": 22114, + "nodeType": "Return", + "src": "23038:12:59" + } + ] + } + }, + { + "body": { + "id": 22147, + "nodeType": "Block", + "src": "23137:184:59", + "statements": [ + { + "condition": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22139, + "name": "_delegate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22098, + "src": "23239:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22140, + "name": "_module", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22100, + "src": "23250:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22141, + "name": "_perm", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22102, + "src": "23259:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22131, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "23174:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 22133, + "indexExpression": { + "argumentTypes": null, + "id": 22132, + "name": "PERMISSIONMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10019, + "src": "23182:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23174:30:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 22135, + "indexExpression": { + "argumentTypes": null, + "id": 22134, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22118, + "src": "23205:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23174:33:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_ModuleData_$20648_storage", + "typeString": "struct SecurityToken.ModuleData storage ref" + } + }, + "id": 22136, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "moduleAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 20647, + "src": "23174:47:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22130, + "name": "IPermissionManager", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 13247, + "src": "23155:18:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IPermissionManager_$13247_$", + "typeString": "type(contract IPermissionManager)" + } + }, + "id": 22137, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23155:67:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_IPermissionManager_$13247", + "typeString": "contract IPermissionManager" + } + }, + "id": 22138, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "checkPermission", + "nodeType": "MemberAccess", + "referencedDeclaration": 13226, + "src": "23155:83:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_address_$_t_address_$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (address,address,bytes32) view external returns (bool)" + } + }, + "id": 22142, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23155:110:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22146, + "nodeType": "IfStatement", + "src": "23151:160:59", + "trueBody": { + "id": 22145, + "nodeType": "Block", + "src": "23267:44:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22143, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23292:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 22106, + "id": 22144, + "nodeType": "Return", + "src": "23285:11:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22126, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22121, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22118, + "src": "23089:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22122, + "name": "modules", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20676, + "src": "23093:7:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_uint8_$_t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage_$", + "typeString": "mapping(uint8 => struct SecurityToken.ModuleData storage ref[] storage ref)" + } + }, + "id": 22124, + "indexExpression": { + "argumentTypes": null, + "id": 22123, + "name": "PERMISSIONMANAGER_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10019, + "src": "23101:21:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "23093:30:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_ModuleData_$20648_storage_$dyn_storage", + "typeString": "struct SecurityToken.ModuleData storage ref[] storage ref" + } + }, + "id": 22125, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "23093:37:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "23089:41:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22148, + "initializationExpression": { + "assignments": [ + 22118 + ], + "declarations": [ + { + "constant": false, + "id": 22118, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "23076:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 22117, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "23076:5:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22120, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22119, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23086:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "23076:11:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 22128, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "23132:3:59", + "subExpression": { + "argumentTypes": null, + "id": 22127, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22118, + "src": "23132:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 22129, + "nodeType": "ExpressionStatement", + "src": "23132:3:59" + }, + "nodeType": "ForStatement", + "src": "23071:250:59" + } + ] + }, + "documentation": "@notice Validate permissions with PermissionManager if it exists, If no Permission return false\n@dev Note that IModule withPerm will allow ST owner all permissions anyway\n@dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions)\n@param _delegate address of delegate\n@param _module address of PermissionManager module\n@param _perm the permissions\n@return success", + "id": 22150, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "checkPermission", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22103, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22098, + "name": "_delegate", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22889:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22097, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22889:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22100, + "name": "_module", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22908:15:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22099, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "22908:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22102, + "name": "_perm", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22925:13:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 22101, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "22925:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22888:51:59" + }, + "payable": false, + "returnParameters": { + "id": 22106, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22105, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22150, + "src": "22960:4:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 22104, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "22960:4:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "22959:6:59" + }, + "scope": 22534, + "src": "22864:463:59", + "stateMutability": "view", + "superFunction": 10048, + "visibility": "public" + }, + { + "body": { + "id": 22163, + "nodeType": "Block", + "src": "23560:57:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22161, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22157, + "name": "tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20640, + "src": "23570:11:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22159, + "name": "_tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22152, + "src": "23597:12:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22158, + "name": "ITokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10218, + "src": "23584:12:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ITokenBurner_$10218_$", + "typeString": "type(contract ITokenBurner)" + } + }, + "id": 22160, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23584:26:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "src": "23570:40:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "id": 22162, + "nodeType": "ExpressionStatement", + "src": "23570:40:59" + } + ] + }, + "documentation": "@notice used to set the token Burner address. It only be called by the owner\n@param _tokenBurner Address of the token burner contract", + "id": 22164, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": null, + "id": 22155, + "modifierName": { + "argumentTypes": null, + "id": 22154, + "name": "onlyOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22789, + "src": "23550:9:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "23550:9:59" + } + ], + "name": "setTokenBurner", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22153, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22152, + "name": "_tokenBurner", + "nodeType": "VariableDeclaration", + "scope": 22164, + "src": "23521:20:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22151, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "23521:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23520:22:59" + }, + "payable": false, + "returnParameters": { + "id": 22156, + "nodeType": "ParameterList", + "parameters": [], + "src": "23560:0:59" + }, + "scope": 22534, + "src": "23497:120:59", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 22265, + "nodeType": "Block", + "src": "23811:931:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22173, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "23841:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22174, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "23841:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22176, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23861:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22175, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "23853:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22177, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23853:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22178, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "23865:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22172, + "name": "adjustInvestorCount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21510, + "src": "23821:19:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 22179, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23821:51:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22180, + "nodeType": "ExpressionStatement", + "src": "23821:51:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 22186, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22182, + "name": "tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20640, + "src": "23890:11:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22184, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23913:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22183, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "23905:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22185, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23905:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "23890:25:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "546f6b656e204275726e657220636f6e74726163742061646472657373206973206e6f742073657420796574", + "id": 22187, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "23917:46:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b1e20e36cf137ffa348b540450b55b5e970f06fe4fc7c40c3990ff61e4871e2f", + "typeString": "literal_string \"Token Burner contract address is not set yet\"" + }, + "value": "Token Burner contract address is not set yet" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b1e20e36cf137ffa348b540450b55b5e970f06fe4fc7c40c3990ff61e4871e2f", + "typeString": "literal_string \"Token Burner contract address is not set yet\"" + } + ], + "id": 22181, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "23882:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22188, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23882:82:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22189, + "nodeType": "ExpressionStatement", + "src": "23882:82:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22192, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "23997:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22193, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "23997:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22195, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24017:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22194, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24009:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22196, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24009:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22197, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24021:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22191, + "name": "verifyTransfer", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 21932 + ], + "referencedDeclaration": 21932, + "src": "23982:14:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,address,uint256) returns (bool)" + } + }, + "id": 22198, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23982:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "5472616e73666572206973206e6f742076616c6964", + "id": 22199, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24030:23:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + }, + "value": "Transfer is not valid" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_c2b52aede81a61bfb2345b48703ab4dd0a83b05e6407bea4090bfcc23659ff5b", + "typeString": "literal_string \"Transfer is not valid\"" + } + ], + "id": 22190, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "23974:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22200, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "23974:80:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22201, + "nodeType": "ExpressionStatement", + "src": "23974:80:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22208, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22203, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24072:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22204, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "24082:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22207, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22205, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24091:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22206, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24091:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24082:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "24072:30:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "56616c75652073686f756c64206e6f2062652067726561746572207468616e207468652062616c616e6365206f66206d73672e73656e646572", + "id": 22209, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24104:59:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_b61a8271ddd9a6e3d197611651578d62cfc7171b9d88bf350a7c0ea036caf1ea", + "typeString": "literal_string \"Value should no be greater than the balance of msg.sender\"" + }, + "value": "Value should no be greater than the balance of msg.sender" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_b61a8271ddd9a6e3d197611651578d62cfc7171b9d88bf350a7c0ea036caf1ea", + "typeString": "literal_string \"Value should no be greater than the balance of msg.sender\"" + } + ], + "id": 22202, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "24064:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22210, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24064:100:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22211, + "nodeType": "ExpressionStatement", + "src": "24064:100:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22213, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24199:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22214, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24199:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22212, + "name": "adjustBalanceCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21653, + "src": "24174:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 22215, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24174:36:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22216, + "nodeType": "ExpressionStatement", + "src": "24174:36:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 22217, + "name": "adjustTotalSupplyCheckpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21638, + "src": "24220:28:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$__$returns$__$", + "typeString": "function ()" + } + }, + "id": 22218, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24220:30:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22219, + "nodeType": "ExpressionStatement", + "src": "24220:30:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22231, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22220, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "24440:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22223, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22221, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24449:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22222, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24449:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "24440:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22229, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24488:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22224, + "name": "balances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22854, + "src": "24463:8:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 22227, + "indexExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22225, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24472:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22226, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24472:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "24463:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22228, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "24463:24:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22230, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24463:32:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "24440:55:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22232, + "nodeType": "ExpressionStatement", + "src": "24440:55:59" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22236, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24530:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22237, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24530:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22238, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24542:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 22234, + "name": "tokenBurner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20640, + "src": "24513:11:59", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ITokenBurner_$10218", + "typeString": "contract ITokenBurner" + } + }, + "id": 22235, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "burn", + "nodeType": "MemberAccess", + "referencedDeclaration": 10217, + "src": "24513:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_address_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (address,uint256) external returns (bool)" + } + }, + "id": 22239, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24513:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "546f6b656e206275726e65722070726f63657373206973206e6f742076616c696461746564", + "id": 22240, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24551:39:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5ccda958cac3717658218d89784f10f8d0a910ee0bbde8a05008990ae73f253b", + "typeString": "literal_string \"Token burner process is not validated\"" + }, + "value": "Token burner process is not validated" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_5ccda958cac3717658218d89784f10f8d0a910ee0bbde8a05008990ae73f253b", + "typeString": "literal_string \"Token burner process is not validated\"" + } + ], + "id": 22233, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23312, + "src": "24505:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 22241, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24505:86:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22242, + "nodeType": "ExpressionStatement", + "src": "24505:86:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22248, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22243, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "24601:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22246, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24633:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 22244, + "name": "totalSupply_", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22856, + "src": "24616:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22245, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sub", + "nodeType": "MemberAccess", + "referencedDeclaration": 22730, + "src": "24616:16:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256) pure returns (uint256)" + } + }, + "id": 22247, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24616:24:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "24601:39:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22249, + "nodeType": "ExpressionStatement", + "src": "24601:39:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22251, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24661:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22252, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24661:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22253, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24673:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22250, + "name": "Burnt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9985, + "src": "24655:5:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 22254, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24655:25:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22255, + "nodeType": "EmitStatement", + "src": "24650:30:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22257, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23308, + "src": "24704:3:59", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 22258, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24704:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 22260, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24724:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 22259, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "24716:7:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 22261, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24716:10:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "argumentTypes": null, + "id": 22262, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "24728:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22256, + "name": "Transfer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23045, + "src": "24695:8:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256)" + } + }, + "id": 22263, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "24695:40:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22264, + "nodeType": "EmitStatement", + "src": "24690:45:59" + } + ] + }, + "documentation": "@notice Burn function used to burn the securityToken\n@param _value No. of token that get burned", + "id": 22266, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 22169, + "name": "_value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22166, + "src": "23796:6:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22170, + "modifierName": { + "argumentTypes": null, + "id": 22168, + "name": "checkGranularity", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20849, + "src": "23779:16:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "23779:24:59" + } + ], + "name": "burn", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22167, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22166, + "name": "_value", + "nodeType": "VariableDeclaration", + "scope": 22266, + "src": "23763:14:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22165, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "23763:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23762:16:59" + }, + "payable": false, + "returnParameters": { + "id": 22171, + "nodeType": "ParameterList", + "parameters": [], + "src": "23811:0:59" + }, + "scope": 22534, + "src": "23749:993:59", + "stateMutability": "nonpayable", + "superFunction": 9973, + "visibility": "public" + }, + { + "body": { + "id": 22323, + "nodeType": "Block", + "src": "24935:197:59", + "statements": [ + { + "assignments": [ + 22274 + ], + "declarations": [ + { + "constant": false, + "id": 22274, + "name": "len", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "24945:8:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22273, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "24945:4:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22283, + "initialValue": { + "argumentTypes": null, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22278, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22275, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22268, + "src": "24956:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 22276, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24956:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "hexValue": "34", + "id": 22277, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24971:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "24956:16:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "argumentTypes": null, + "hexValue": "34", + "id": 22281, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "24990:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "id": 22282, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "24956:35:59", + "trueExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22279, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22268, + "src": "24975:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 22280, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "24975:12:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "24945:46:59" + }, + { + "body": { + "id": 22321, + "nodeType": "Block", + "src": "25032:94:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22319, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22294, + "name": "sig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22271, + "src": "25046:3:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22317, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22297, + "name": "sig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22271, + "src": "25064:3:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "id": 22296, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25059:4:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": "uint" + }, + "id": 22298, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25059:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22316, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22300, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22268, + "src": "25076:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 22302, + "indexExpression": { + "argumentTypes": null, + "id": 22301, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25082:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "25076:8:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + ], + "id": 22299, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25071:4:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": "uint" + }, + "id": 22303, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25071:14:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22314, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "hexValue": "32", + "id": 22304, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25089:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22312, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "hexValue": "38", + "id": 22305, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25095:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_8_by_1", + "typeString": "int_const 8" + }, + "value": "8" + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22310, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22308, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22306, + "name": "len", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22274, + "src": "25100:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22307, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25106:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "25100:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "id": 22309, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25110:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25100:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22311, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "25099:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25095:17:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22313, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "25094:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25089:24:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22315, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "25088:26:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25071:43:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25059:55:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22295, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "25052:6:59", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": "bytes4" + }, + "id": 22318, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25052:63:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "25046:69:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "id": 22320, + "nodeType": "ExpressionStatement", + "src": "25046:69:59" + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22290, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22288, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25018:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 22289, + "name": "len", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22274, + "src": "25022:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25018:7:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22322, + "initializationExpression": { + "assignments": [ + 22285 + ], + "declarations": [ + { + "constant": false, + "id": 22285, + "name": "i", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "25006:6:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22284, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "25006:4:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22287, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22286, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25015:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "25006:10:59" + }, + "loopExpression": { + "expression": { + "argumentTypes": null, + "id": 22292, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "25027:3:59", + "subExpression": { + "argumentTypes": null, + "id": 22291, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22285, + "src": "25027:1:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22293, + "nodeType": "ExpressionStatement", + "src": "25027:3:59" + }, + "nodeType": "ForStatement", + "src": "25001:125:59" + } + ] + }, + "documentation": "@notice Get function signature from _data\n@param _data passed data\n@return bytes4 sig", + "id": 22324, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getSig", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22269, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22268, + "name": "_data", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "24887:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 22267, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "24887:5:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24886:13:59" + }, + "payable": false, + "returnParameters": { + "id": 22272, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22271, + "name": "sig", + "nodeType": "VariableDeclaration", + "scope": 22324, + "src": "24923:10:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 22270, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "24923:6:59", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "24922:12:59" + }, + "scope": 22534, + "src": "24871:261:59", + "stateMutability": "pure", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 22356, + "nodeType": "Block", + "src": "25357:210:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22340, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22334, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25375:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9935" + }, + "id": 22339, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639936_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9936" + }, + "id": 22337, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "hexValue": "32", + "id": 22335, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25397:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "**", + "rightExpression": { + "argumentTypes": null, + "hexValue": "323536", + "id": 22336, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25400:3:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_256_by_1", + "typeString": "int_const 256" + }, + "value": "256" + }, + "src": "25397:6:59", + "typeDescriptions": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639936_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9936" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22338, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25406:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "25397:10:59", + "typeDescriptions": { + "typeIdentifier": "t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1", + "typeString": "int_const 1157...(70 digits omitted)...9935" + } + }, + "src": "25375:32:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 22333, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "25367:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 22341, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25367:41:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22342, + "nodeType": "ExpressionStatement", + "src": "25367:41:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22347, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22343, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25418:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22346, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22344, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25440:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22345, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25462:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "25440:23:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "25418:45:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22348, + "nodeType": "ExpressionStatement", + "src": "25418:45:59" + }, + { + "eventCall": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22350, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25499:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "id": 22351, + "name": "now", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 23310, + "src": "25520:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22349, + "name": "LogCheckpointCreated", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20739, + "src": "25478:20:59", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 22352, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25478:46:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22353, + "nodeType": "EmitStatement", + "src": "25473:51:59" + }, + { + "expression": { + "argumentTypes": null, + "id": 22354, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "25541:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22332, + "id": 22355, + "nodeType": "Return", + "src": "25534:26:59" + } + ] + }, + "documentation": "@notice Creates a checkpoint that can be used to query historical balances / totalSuppy\n@return uint256", + "id": 22357, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [ + { + "argumentTypes": null, + "id": 22327, + "name": "CHECKPOINT_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10028, + "src": "25318:14:59", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "argumentTypes": null, + "hexValue": "74727565", + "id": 22328, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "25334:4:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "id": 22329, + "modifierName": { + "argumentTypes": null, + "id": 22326, + "name": "onlyModule", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20834, + "src": "25307:10:59", + "typeDescriptions": { + "typeIdentifier": "t_modifier$_t_uint8_$_t_bool_$", + "typeString": "modifier (uint8,bool)" + } + }, + "nodeType": "ModifierInvocation", + "src": "25307:32:59" + } + ], + "name": "createCheckpoint", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22325, + "nodeType": "ParameterList", + "parameters": [], + "src": "25297:2:59" + }, + "payable": false, + "returnParameters": { + "id": 22332, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22331, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22357, + "src": "25348:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22330, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25348:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25347:9:59" + }, + "scope": 22534, + "src": "25272:295:59", + "stateMutability": "nonpayable", + "superFunction": 10091, + "visibility": "public" + }, + { + "body": { + "id": 22371, + "nodeType": "Block", + "src": "25800:87:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22365, + "name": "checkpointTotalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20661, + "src": "25828:21:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "id": 22366, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22359, + "src": "25851:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 22367, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22864 + ], + "referencedDeclaration": 22864, + "src": "25866:11:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 22368, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25866:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22364, + "name": "getValueAt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22513, + "src": "25817:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256,uint256) view returns (uint256)" + } + }, + "id": 22369, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "25817:63:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22363, + "id": 22370, + "nodeType": "Return", + "src": "25810:70:59" + } + ] + }, + "documentation": "@notice Queries totalSupply as of a defined checkpoint\n@param _checkpointId Checkpoint ID to query\n@return uint256", + "id": 22372, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "totalSupplyAt", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22360, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22359, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 22372, + "src": "25748:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22358, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25748:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25747:23:59" + }, + "payable": false, + "returnParameters": { + "id": 22363, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22362, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22372, + "src": "25791:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22361, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "25791:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "25790:9:59" + }, + "scope": 22534, + "src": "25725:162:59", + "stateMutability": "view", + "superFunction": 10077, + "visibility": "public" + }, + { + "body": { + "id": 22512, + "nodeType": "Block", + "src": "26280:1167:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22387, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22385, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26298:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<=", + "rightExpression": { + "argumentTypes": null, + "id": 22386, + "name": "currentCheckpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10032, + "src": "26315:19:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26298:36:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 22384, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 23311, + 23312 + ], + "referencedDeclaration": 23311, + "src": "26290:7:59", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$", + "typeString": "function (bool) pure" + } + }, + "id": 22388, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "26290:45:59", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 22389, + "nodeType": "ExpressionStatement", + "src": "26290:45:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22392, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22390, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26440:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22391, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26457:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "26440:18:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22396, + "nodeType": "IfStatement", + "src": "26436:55:59", + "trueBody": { + "id": 22395, + "nodeType": "Block", + "src": "26460:31:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22393, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26479:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "functionReturnParameters": 22383, + "id": 22394, + "nodeType": "Return", + "src": "26472:8:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22397, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26504:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22398, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26504:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22399, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26526:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "26504:23:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22404, + "nodeType": "IfStatement", + "src": "26500:74:59", + "trueBody": { + "id": 22403, + "nodeType": "Block", + "src": "26529:45:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22401, + "name": "_currentValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22379, + "src": "26550:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22402, + "nodeType": "Return", + "src": "26543:20:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22410, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22405, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26587:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22407, + "indexExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22406, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26599:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26587:14:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22408, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "26587:27:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "argumentTypes": null, + "id": 22409, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26618:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26587:44:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22417, + "nodeType": "IfStatement", + "src": "26583:102:59", + "trueBody": { + "id": 22416, + "nodeType": "Block", + "src": "26633:52:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22411, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26654:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22413, + "indexExpression": { + "argumentTypes": null, + "hexValue": "30", + "id": 22412, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26666:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26654:14:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22414, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 20652, + "src": "26654:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22415, + "nodeType": "Return", + "src": "26647:27:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22426, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22418, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26698:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22423, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22422, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22419, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26710:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22420, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26710:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22421, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26731:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "26710:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26698:35:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22424, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "26698:48:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 22425, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26749:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26698:64:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22430, + "nodeType": "IfStatement", + "src": "26694:115:59", + "trueBody": { + "id": 22429, + "nodeType": "Block", + "src": "26764:45:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22427, + "name": "_currentValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22379, + "src": "26785:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22428, + "nodeType": "Return", + "src": "26778:20:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22439, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22431, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26822:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22436, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22435, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22432, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26834:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22433, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26834:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22434, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26855:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "26834:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26822:35:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22437, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "26822:48:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 22438, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "26874:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "26822:65:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22449, + "nodeType": "IfStatement", + "src": "26818:144:59", + "trueBody": { + "id": 22448, + "nodeType": "Block", + "src": "26889:73:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22440, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26910:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22445, + "indexExpression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22444, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22441, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "26922:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22442, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "26922:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22443, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26943:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "26922:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "26910:35:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22446, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 20652, + "src": "26910:41:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22447, + "nodeType": "Return", + "src": "26903:48:59" + } + ] + } + }, + { + "assignments": [ + 22451 + ], + "declarations": [ + { + "constant": false, + "id": 22451, + "name": "min", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26971:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22450, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26971:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22453, + "initialValue": { + "argumentTypes": null, + "hexValue": "30", + "id": 22452, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "26985:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "26971:15:59" + }, + { + "assignments": [ + 22455 + ], + "declarations": [ + { + "constant": false, + "id": 22455, + "name": "max", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26996:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22454, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26996:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22460, + "initialValue": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22459, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 22456, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27010:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22457, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "length", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "27010:18:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22458, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27031:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "27010:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "26996:36:59" + }, + { + "body": { + "id": 22505, + "nodeType": "Block", + "src": "27060:342:59", + "statements": [ + { + "assignments": [ + 22465 + ], + "declarations": [ + { + "constant": false, + "id": 22465, + "name": "mid", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "27074:11:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22464, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27074:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 22472, + "initialValue": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22471, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "components": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22468, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22466, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27089:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "id": 22467, + "name": "min", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22451, + "src": "27095:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27089:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 22469, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "27088:11:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "/", + "rightExpression": { + "argumentTypes": null, + "hexValue": "32", + "id": 22470, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27102:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "27088:15:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "27074:29:59" + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22478, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22473, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27121:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22475, + "indexExpression": { + "argumentTypes": null, + "id": 22474, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27133:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27121:16:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22476, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "27121:29:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 22477, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "27154:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27121:46:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 22485, + "nodeType": "IfStatement", + "src": "27117:117:59", + "trueBody": { + "id": 22484, + "nodeType": "Block", + "src": "27169:65:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22481, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22479, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27187:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 22480, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27193:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27187:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22482, + "nodeType": "ExpressionStatement", + "src": "27187:9:59" + }, + { + "id": 22483, + "nodeType": "Break", + "src": "27214:5:59" + } + ] + } + }, + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22491, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22486, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27251:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22488, + "indexExpression": { + "argumentTypes": null, + "id": 22487, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27263:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27251:16:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22489, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "checkpointId", + "nodeType": "MemberAccess", + "referencedDeclaration": 20650, + "src": "27251:29:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "argumentTypes": null, + "id": 22490, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22377, + "src": "27283:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27251:45:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 22503, + "nodeType": "Block", + "src": "27350:42:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22501, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22499, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27368:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 22500, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27374:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27368:9:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22502, + "nodeType": "ExpressionStatement", + "src": "27368:9:59" + } + ] + }, + "id": 22504, + "nodeType": "IfStatement", + "src": "27247:145:59", + "trueBody": { + "id": 22498, + "nodeType": "Block", + "src": "27298:46:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 22496, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 22492, + "name": "min", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22451, + "src": "27316:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22495, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22493, + "name": "mid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22465, + "src": "27322:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "argumentTypes": null, + "hexValue": "31", + "id": 22494, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "27328:1:59", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "27322:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27316:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 22497, + "nodeType": "ExpressionStatement", + "src": "27316:13:59" + } + ] + } + } + ] + }, + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 22463, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 22461, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27049:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "argumentTypes": null, + "id": 22462, + "name": "min", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22451, + "src": "27055:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "27049:9:59", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22506, + "nodeType": "WhileStatement", + "src": "27042:360:59" + }, + { + "expression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22507, + "name": "checkpoints", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22375, + "src": "27418:11:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage pointer" + } + }, + "id": 22509, + "indexExpression": { + "argumentTypes": null, + "id": 22508, + "name": "max", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22455, + "src": "27430:3:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27418:16:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref" + } + }, + "id": 22510, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 20652, + "src": "27418:22:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22383, + "id": 22511, + "nodeType": "Return", + "src": "27411:29:59" + } + ] + }, + "documentation": "@notice Queries value at a defined checkpoint\n@param checkpoints is array of Checkpoint objects\n@param _checkpointId Checkpoint ID to query\n@param _currentValue Current value of checkpoint\n@return uint256", + "id": 22513, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "getValueAt", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22380, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22375, + "name": "checkpoints", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26169:32:59", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + }, + "typeName": { + "baseType": { + "contractScope": null, + "id": 22373, + "name": "Checkpoint", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 20653, + "src": "26169:10:59", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Checkpoint_$20653_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint" + } + }, + "id": 22374, + "length": null, + "nodeType": "ArrayTypeName", + "src": "26169:12:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr", + "typeString": "struct SecurityToken.Checkpoint[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22377, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26203:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22376, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26203:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22379, + "name": "_currentValue", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26226:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22378, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26226:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26168:80:59" + }, + "payable": false, + "returnParameters": { + "id": 22383, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22382, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22513, + "src": "26271:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22381, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "26271:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "26270:9:59" + }, + "scope": 22534, + "src": "26149:1298:59", + "stateMutability": "view", + "superFunction": null, + "visibility": "internal" + }, + { + "body": { + "id": 22532, + "nodeType": "Block", + "src": "27731:102:59", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "baseExpression": { + "argumentTypes": null, + "id": 22523, + "name": "checkpointBalances", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 20658, + "src": "27759:18:59", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_$", + "typeString": "mapping(address => struct SecurityToken.Checkpoint storage ref[] storage ref)" + } + }, + "id": 22525, + "indexExpression": { + "argumentTypes": null, + "id": 22524, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22515, + "src": "27778:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "27759:29:59", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + } + }, + { + "argumentTypes": null, + "id": 22526, + "name": "_checkpointId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22517, + "src": "27790:13:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 22528, + "name": "_investor", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22515, + "src": "27815:9:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 22527, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 22936 + ], + "referencedDeclaration": 22936, + "src": "27805:9:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$returns$_t_uint256_$", + "typeString": "function (address) view returns (uint256)" + } + }, + "id": 22529, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "27805:20:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage", + "typeString": "struct SecurityToken.Checkpoint storage ref[] storage ref" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 22522, + "name": "getValueAt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22513, + "src": "27748:10:59", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_array$_t_struct$_Checkpoint_$20653_storage_$dyn_storage_ptr_$_t_uint256_$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (struct SecurityToken.Checkpoint storage ref[] storage pointer,uint256,uint256) view returns (uint256)" + } + }, + "id": 22530, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "27748:78:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 22521, + "id": 22531, + "nodeType": "Return", + "src": "27741:85:59" + } + ] + }, + "documentation": "@notice Queries balances as of a defined checkpoint\n@param _investor Investor to query balance for\n@param _checkpointId Checkpoint ID to query as of", + "id": 22533, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": true, + "modifiers": [], + "name": "balanceOfAt", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22518, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22515, + "name": "_investor", + "nodeType": "VariableDeclaration", + "scope": 22533, + "src": "27660:17:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 22514, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "27660:7:59", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 22517, + "name": "_checkpointId", + "nodeType": "VariableDeclaration", + "scope": 22533, + "src": "27679:21:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22516, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27679:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "27659:42:59" + }, + "payable": false, + "returnParameters": { + "id": 22521, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 22520, + "name": "", + "nodeType": "VariableDeclaration", + "scope": 22533, + "src": "27722:7:59", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 22519, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "27722:7:59", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "27721:9:59" + }, + "scope": 22534, + "src": "27639:194:59", + "stateMutability": "view", + "superFunction": 10086, + "visibility": "public" + } + ], + "scope": 22535, + "src": "928:26908:59" + } + ], + "src": "0:27837:59" + }, + "compiler": { + "name": "solc", + "version": "0.4.24+commit.e67f0147.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.1", + "updatedAt": "2018-10-08T11:54:57.746Z" +} \ No newline at end of file diff --git a/CLI/data/accredited_data.csv b/CLI/data/accredited_data.csv index 8a322e81f..0d13f1ad0 100644 --- a/CLI/data/accredited_data.csv +++ b/CLI/data/accredited_data.csv @@ -1,10 +1,10 @@ -0xf26bb01507a076c83e26d3c8d0f2eab7b77f96f2,true -0xb42de462906eb0f6a10c7bdf5b100c5da9dc376c,true -0x3270d07c6552d6334e485c4e8af41ce9e0c34cfd,true -0x92fdab26ac0c7ae2a40d45b09c9f74846697c40a,false -0xf1819ecb5e81a8f8c0f1d325c8de017caf4fd4fb,false -0xa26cc0567e29fda3c77369791e926b4c46456fcb,false -0x97c09f763a699a51cb947f95e602c08f7bcba202,false -0x308a3ea530e5b160f1f7115f2ddb30cb44d8b54d,false -0xbc1bfb5d90692854672febe76ca5379dea1015e4,false -0x7442dcd2eb074ea6dbfaa8338300bc86238c2aae,false +0xee7ae74d964f2be7d72c1b187b38e2ed3615d4d1,true +0x2f0fd672bf222413cc69dc1f4f1d7e93ad1763a1,true +0xac297053173b02b02a737d47f7b4a718e5b170ef,true +0x49fc0b78238dab644698a90fa351b4c749e123d2,false +0x10223927009b8add0960359dd90d1449415b7ca9,false +0x3c65cfe3de848cf38e9d76e9c3e57a2f1140b399,false +0xabf60de3265b3017db7a1be66fc8b364ec1dbb98,false +0xb841fe5a89da1bbef2d0805fbd7ffcbbb2fca5e3,false +0x56be93088141b16ebaa9416122fd1d928da25ecf,false +0xbb276b6f68f0a41d54b7e0a608fe8eb1ebdee7b0,false \ No newline at end of file diff --git a/CLI/data/dividendsExclusions_data.csv b/CLI/data/dividendsExclusions_data.csv index b418985eb..bd8715437 100644 --- a/CLI/data/dividendsExclusions_data.csv +++ b/CLI/data/dividendsExclusions_data.csv @@ -1,6 +1,4 @@ -0xa26cc0567e29fda3c77369791e926b4c46456fcb -0x97c09f763a699a51cb947f95e602c08f7bcba202 -0x308a3ea530e5b160f1f7115f2ddb30cb44d8b54d -0xbc1bfb5d90692854672febe76ca5379dea1015e4 -0x7442dcd2eb074ea6dbfaa8338300bc86238c2aae -0x0a519b4b6501f92e8f516230b97aca83257b0c01 \ No newline at end of file +0x49fc0b78238dab644698a90fa351b4c749e123d2 +0x10223927009b8add0960359dd90d1449415b7ca9 +0x3c65cfe3de848cf38e9d76e9c3e57a2f1140b399 +0xabf60de3265b3017db7a1be66fc8b364ec1dbb98 \ No newline at end of file diff --git a/CLI/data/multi_mint_data.csv b/CLI/data/multi_mint_data.csv index 1019378bc..0b157b164 100644 --- a/CLI/data/multi_mint_data.csv +++ b/CLI/data/multi_mint_data.csv @@ -1,10 +1,10 @@ -0xdb49fc01ca36c4d687973ef1da8343d453d1179e,1000 -0xb42de462906eb0f6a10c7bdf5b100c5da9dc376c,1000 -0x3270d07c6552d6334e485c4e8af41ce9e0c34cfd,1000 -0x92fdab26ac0c7ae2a40d45b09c9f74846697c40a,1000 -0xf1819ecb5e81a8f8c0f1d325c8de017caf4fd4fb,1000 -0xa26cc0567e29fda3c77369791e926b4c46456fcb,1000 -0x97c09f763a699a51cb947f95e602c08f7bcba202,1000 -0x308a3ea530e5b160f1f7115f2ddb30cb44d8b54d,1000 -0xbc1bfb5d90692854672febe76ca5379dea1015e4,1000 -0x7442dcd2eb074ea6dbfaa8338300bc86238c2aae,1000 \ No newline at end of file +0xee7ae74d964f2be7d72c1b187b38e2ed3615d4d1,1000 +0x2f0fd672bf222413cc69dc1f4f1d7e93ad1763a1,1000 +0xac297053173b02b02a737d47f7b4a718e5b170ef,1000 +0x49fc0b78238dab644698a90fa351b4c749e123d2,1000 +0x10223927009b8add0960359dd90d1449415b7ca9,1000 +0x3c65cfe3de848cf38e9d76e9c3e57a2f1140b399,1000 +0xabf60de3265b3017db7a1be66fc8b364ec1dbb98,1000 +0xb841fe5a89da1bbef2d0805fbd7ffcbbb2fca5e3,1000 +0x56be93088141b16ebaa9416122fd1d928da25ecf,1000 +0xbb276b6f68f0a41d54b7e0a608fe8eb1ebdee7b0,1000 \ No newline at end of file diff --git a/CLI/data/nonAccreditedLimits_data.csv b/CLI/data/nonAccreditedLimits_data.csv index 824e92063..c4705f372 100644 --- a/CLI/data/nonAccreditedLimits_data.csv +++ b/CLI/data/nonAccreditedLimits_data.csv @@ -1,10 +1,7 @@ -0xf26bb01507a076c83e26d3c8d0f2eab7b77f96f2,3000 -0xb42de462906eb0f6a10c7bdf5b100c5da9dc376c,5000 -0x3270d07c6552d6334e485c4e8af41ce9e0c34cfd,1000 -0x92fdab26ac0c7ae2a40d45b09c9f74846697c40a,2 -0xf1819ecb5e81a8f8c0f1d325c8de017caf4fd4fb,1000.500 -0xa26cc0567e29fda3c77369791e926b4c46456fcb,1 -0x97c09f763a699a51cb947f95e602c08f7bcba202,10000 -0x308a3ea530e5b160f1f7115f2ddb30cb44d8b54d,10000 -0xbc1bfb5d90692854672febe76ca5379dea1015e4,10000 -0x7442dcd2eb074ea6dbfaa8338300bc86238c2aae,10000 +0x49fc0b78238dab644698a90fa351b4c749e123d2,2000 +0x10223927009b8add0960359dd90d1449415b7ca9,1000 +0x3c65cfe3de848cf38e9d76e9c3e57a2f1140b399,2500 +0xabf60de3265b3017db7a1be66fc8b364ec1dbb98,500 +0xb841fe5a89da1bbef2d0805fbd7ffcbbb2fca5e3,3500 +0x56be93088141b16ebaa9416122fd1d928da25ecf,5000 +0xbb276b6f68f0a41d54b7e0a608fe8eb1ebdee7b0,2000 diff --git a/CLI/data/whitelist_data.csv b/CLI/data/whitelist_data.csv index d54fc51ee..3276dec64 100644 --- a/CLI/data/whitelist_data.csv +++ b/CLI/data/whitelist_data.csv @@ -1,11 +1,10 @@ -0xf26bb01507a076c83e26d3c8d0f2eab7b77f96f2,5/5/2018,1/8/2018,10/10/2018,true -0xb42de462906eb0f6a10c7bdf5b100c5da9dc376c,5/5/2018,1/8/2018,10/10/2018,true -0x3270d07c6552d6334e485c4e8af41ce9e0c34cfd,5/5/2018,1/8/2018,10/10/2018,true -0x92fdab26ac0c7ae2a40d45b09c9f74846697c40a,5/5/2018,1/8/2018,10/10/2018,false -0xf1819ecb5e81a8f8c0f1d325c8de017caf4fd4fb,5/5/2018,1/8/2018,10/10/2018,false -0xa26cc0567e29fda3c77369791e926b4c46456fcb,5/5/2018,1/8/2018,10/10/2018,false -0x97c09f763a699a51cb947f95e602c08f7bcba202,5/5/2018,1/8/2018,10/10/2018,false -0x308a3ea530e5b160f1f7115f2ddb30cb44d8b54d,5/5/2018,1/8/2018,10/10/2018,false -0xbc1bfb5d90692854672febe76ca5379dea1015e4,5/5/2018,1/8/2018,10/10/2018,false -0x94ee9fbc9400e81a2bd9a0b9b38491c747ae1b97,5/5/2018,1/8/2018,10/10/2018,true -0x7fc77e5420e7c2cdff2dca5e0cc180da51b39683,5/5/2018,1/8/2018,10/10/2018,true \ No newline at end of file +0xee7ae74d964f2be7d72c1b187b38e2ed3615d4d1,5/5/2018,1/8/2018,10/10/2019,true +0x2f0fd672bf222413cc69dc1f4f1d7e93ad1763a1,5/5/2018,1/8/2018,10/10/2019,true +0xac297053173b02b02a737d47f7b4a718e5b170ef,5/5/2018,1/8/2018,10/10/2019,true +0x49fc0b78238dab644698a90fa351b4c749e123d2,5/5/2018,1/8/2018,10/10/2019,false +0x10223927009b8add0960359dd90d1449415b7ca9,5/5/2018,1/8/2018,10/10/2019,false +0x3c65cfe3de848cf38e9d76e9c3e57a2f1140b399,5/5/2018,1/8/2018,10/10/2019,false +0xabf60de3265b3017db7a1be66fc8b364ec1dbb98,5/5/2018,1/8/2018,10/10/2019,false +0xb841fe5a89da1bbef2d0805fbd7ffcbbb2fca5e3,5/5/2018,1/8/2018,10/10/2019,false +0x56be93088141b16ebaa9416122fd1d928da25ecf,5/5/2018,1/8/2018,10/10/2019,false +0xbb276b6f68f0a41d54b7e0a608fe8eb1ebdee7b0,5/5/2018,1/8/2018,10/10/2019,true diff --git a/CLI/package-lock.json b/CLI/package-lock.json index bbca71e53..fd1d928a7 100644 --- a/CLI/package-lock.json +++ b/CLI/package-lock.json @@ -318,9 +318,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "requires": { "delayed-stream": "1.0.0" } @@ -866,6 +866,16 @@ "asynckit": "0.4.0", "combined-stream": "1.0.6", "mime-types": "2.1.20" + }, + "dependencies": { + "combined-stream": { + "version": "1.0.6", + "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "1.0.0" + } + } } }, "forwarded": { @@ -1221,6 +1231,11 @@ "sha3": "1.2.2" } }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1659,7 +1674,7 @@ "aws-sign2": "0.7.0", "aws4": "1.8.0", "caseless": "0.12.0", - "combined-stream": "1.0.6", + "combined-stream": "1.0.7", "extend": "3.0.2", "forever-agent": "0.6.1", "form-data": "2.3.2", @@ -1678,6 +1693,25 @@ "uuid": "3.3.2" } }, + "request-promise": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", + "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", + "requires": { + "bluebird": "3.5.2", + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1", + "tough-cookie": "2.4.3" + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "4.17.11" + } + }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -1861,6 +1895,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", diff --git a/CLI/package.json b/CLI/package.json index 20cec3b19..92430ac59 100644 --- a/CLI/package.json +++ b/CLI/package.json @@ -13,6 +13,8 @@ "commander": "^2.16.0", "moment": "^2.22.2", "readline-sync": "^1.4.9", + "request": "^2.88.0", + "request-promise": "^4.2.2", "web3": "^1.0.0-beta.35" } } diff --git a/CLI/polymath-cli.js b/CLI/polymath-cli.js index 43d6c4c88..a9c4d1dd9 100644 --- a/CLI/polymath-cli.js +++ b/CLI/polymath-cli.js @@ -135,11 +135,11 @@ program }); program - .command('strMigrator [fromStrAddress] [toStrAddress]') + .command('strMigrator [toStrAddress] [fromTrAddress] [fromStrAddress]') .alias('str') .description('Runs STR Migrator') - .action(async function(fromStrAddress, toStrAddress) { - await strMigrator.executeApp(fromStrAddress, toStrAddress, program.remoteNode); + .action(async function(toStrAddress, fromTrAddress, fromStrAddress) { + await strMigrator.executeApp(toStrAddress, fromTrAddress, fromStrAddress, program.remoteNode); }); program.parse(process.argv); diff --git a/UPGRADE-PROCEDURES.md b/UPGRADE-PROCEDURES.md index 258e6b5ec..8351b5d26 100644 --- a/UPGRADE-PROCEDURES.md +++ b/UPGRADE-PROCEDURES.md @@ -1,3 +1,17 @@ +## 1.4.0 -> 2.0.0 + +### SecurityTokenRegistry + +1. Migrate existing Tickers and Security Tokens +- a) Run strMigrator command on polymath-cli +- b) Enter the SecurityTokenRegistry v2.0.0 address +- c) Enter the TickerRegistry v1.4.0 address +- d) Tickers are read and listed. +- e) Enter 'y' to migrate all listed tickers +- f) Enter the SecurityTokenRegistry v1.4.0 address +- g) Security Tokens are read and listed +- h) Enter 'y' to migrate all listed Security Tokens + ## 1.3.0 -> 1.4.0 ### USDTieredSTO & Oracles diff --git a/package.json b/package.json index 9b907874f..09e428066 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "openzeppelin-solidity": "1.10.0", "prettier": "^1.14.3", "readline-sync": "^1.4.9", + "request-promise": "^4.2.2", "shelljs": "^0.8.2", "solc": "^0.4.24", "truffle-contract": "^3.0.4", diff --git a/yarn.lock b/yarn.lock index a8bd158f0..d9b04bce4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3032,6 +3032,10 @@ fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" +fs@0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + fsevents@^1.0.0, fsevents@^1.1.2: version "1.2.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.3.tgz#08292982e7059f6674c93d8b829c1e8604979ac0" @@ -4115,6 +4119,10 @@ lodash@=4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +lodash@^4.13.1: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + lodash@^4.17.4: version "4.17.5" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" @@ -5349,6 +5357,21 @@ req-from@^1.0.1: dependencies: resolve-from "^2.0.0" +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + request@^2.67.0, request@^2.79.0: version "2.85.0" resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" @@ -6017,6 +6040,10 @@ stdio@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/stdio/-/stdio-0.2.7.tgz#a1c57da10fe1cfaa0c3bf683c9d0743d1b660839" +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" @@ -6341,19 +6368,19 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@~2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - dependencies: - punycode "^1.4.1" - -tough-cookie@~2.4.3: +tough-cookie@>=2.3.3, tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" dependencies: psl "^1.1.24" punycode "^1.4.1" +tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + tree-kill@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.0.tgz#5846786237b4239014f05db156b643212d4c6f36" From 43689ccf336702ef42e44de5dea5a8e1c28f06a8 Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Wed, 10 Oct 2018 20:35:57 -0300 Subject: [PATCH 120/142] Cli minor updates (#331) * CLI fix for whitelist command * Fix for POLY transfer out of gas error * CLI fix for scripts on remote nodes * CLI: Allow any combination of raise types for USDTieredSTO * Remove CLI restriction to mint tokens if STO is attached * KYC expiry verification --- CLI/commands/ST20Generator.js | 44 +++++++++++++----------- CLI/commands/accredit.js | 1 + CLI/commands/changeNonAccreditedLimit.js | 1 + CLI/commands/dividends_manager.js | 25 ++++++-------- CLI/commands/investor_portal.js | 16 +++++++-- CLI/commands/module_manager.js | 5 --- CLI/commands/multi_mint.js | 42 ++++++++++++++++------ CLI/commands/scripts/script.sh | 8 ++--- CLI/commands/whitelist.js | 1 + CLI/polymath-cli.js | 2 +- 10 files changed, 86 insertions(+), 59 deletions(-) diff --git a/CLI/commands/ST20Generator.js b/CLI/commands/ST20Generator.js index d6ca10a32..24ccdcbbb 100644 --- a/CLI/commands/ST20Generator.js +++ b/CLI/commands/ST20Generator.js @@ -45,11 +45,14 @@ let _tokenConfig; let _mintingConfig; let _stoConfig; +let network; + async function executeApp(tokenConfig, mintingConfig, stoConfig, remoteNetwork) { _tokenConfig = tokenConfig; _mintingConfig = mintingConfig; _stoConfig = stoConfig; + network = remoteNetwork; await global.initialize(remoteNetwork); common.logAsciiBull(); @@ -257,11 +260,11 @@ async function step_Wallet_Issuance(){ async function multi_mint_tokens() { //await whitelist.startWhitelisting(tokenSymbol); - shell.exec(`${__dirname}/scripts/script.sh Whitelist ${tokenSymbol} 75`); + shell.exec(`${__dirname}/scripts/script.sh Whitelist ${tokenSymbol} 75 ${network}`); console.log(chalk.green(`\nCongrats! All the affiliates get succssfully whitelisted, Now its time to Mint the tokens\n`)); console.log(chalk.red(`WARNING: `) + `Please make sure all the addresses that get whitelisted are only eligible to hold or get Security token\n`); - shell.exec(`${__dirname}/scripts//script.sh Multimint ${tokenSymbol} 75`); + shell.exec(`${__dirname}/scripts//script.sh Multimint ${tokenSymbol} 75 ${network}`); console.log(chalk.green(`\nHurray!! Tokens get successfully Minted and transfered to token holders`)); } @@ -350,7 +353,7 @@ async function cappedSTO_launch() { process.exit(0); } else { let transferAction = polyToken.methods.transfer(securityToken._address, new BigNumber(transferAmount)); - let receipt = await common.sendTransaction(Issuer, transferAction, defaultGasPrice, 0, 1.5); + let receipt = await common.sendTransaction(Issuer, transferAction, defaultGasPrice, 0, 2); let event = common.getEventFromLogs(polyToken._jsonInterface, receipt.logs, 'Transfer'); console.log(`Number of POLY sent: ${web3.utils.fromWei(new web3.utils.BN(event._value))}`) } @@ -518,19 +521,20 @@ function fundingConfigUSDTieredSTO() { if (typeof _stoConfig !== 'undefined' && _stoConfig.hasOwnProperty('fundingType')) { selectedFunding = _stoConfig.fundingType; } else { - selectedFunding = readlineSync.question('Enter' + chalk.green(` P `) + 'for POLY raise,' + chalk.green(` D `) + 'for DAI raise,' + chalk.green(` E `) + 'for Ether raise or' + chalk.green(` A `) + 'for all (A): ').toUpperCase(); + selectedFunding = readlineSync.question('Enter' + chalk.green(` P `) + 'for POLY raise,' + chalk.green(` D `) + 'for DAI raise,' + chalk.green(` E `) + 'for Ether raise or any combination of them (i.e.'+ chalk.green(` PED `) + 'for all): ').toUpperCase(); } - if (selectedFunding == 'E') { - funding.raiseType = [FUND_RAISE_TYPES.ETH]; + funding.raiseType = []; + if (selectedFunding.includes('E')) { + funding.raiseType.push(FUND_RAISE_TYPES.ETH); } - else if (selectedFunding == 'P') { - funding.raiseType = [FUND_RAISE_TYPES.POLY]; + if (selectedFunding.includes('P')) { + funding.raiseType.push(FUND_RAISE_TYPES.POLY); } - else if (selectedFunding == 'D') { - funding.raiseType = [FUND_RAISE_TYPES.DAI]; + if (selectedFunding.includes('D')) { + funding.raiseType.push(FUND_RAISE_TYPES.DAI); } - else { + if (funding.raiseType.length == 0) { funding.raiseType = [FUND_RAISE_TYPES.ETH, FUND_RAISE_TYPES.POLY, FUND_RAISE_TYPES.DAI]; } @@ -744,17 +748,17 @@ async function usdTieredSTO_launch() { let stoFee = usdTieredSTOFee; let contractBalance = await polyToken.methods.balanceOf(securityToken._address).call(); let requiredAmount = web3.utils.toWei(stoFee.toString(), "ether"); - if (parseInt(contractBalance) < parseInt(requiredAmount)) { - let transferAmount = parseInt(requiredAmount) - parseInt(contractBalance); - let ownerBalance = await polyToken.methods.balanceOf(Issuer.address).call(); - if(parseInt(ownerBalance) < transferAmount) { + if (new web3.utils.BN(contractBalance).lt(new web3.utils.BN(requiredAmount))) { + let transferAmount = (new web3.utils.BN(requiredAmount)).sub(new web3.utils.BN(contractBalance)); + let ownerBalance = new web3.utils.BN(await polyToken.methods.balanceOf(Issuer.address).call()); + if (ownerBalance.lt(transferAmount)) { console.log(chalk.red(`\n**************************************************************************************************************************************************`)); - console.log(chalk.red(`Not enough balance to pay the ${selectedSTO} fee, Requires ${(new BigNumber(transferAmount).dividedBy(new BigNumber(10).pow(18))).toNumber()} POLY but have ${(new BigNumber(ownerBalance).dividedBy(new BigNumber(10).pow(18))).toNumber()} POLY. Access POLY faucet to get the POLY to complete this txn`)); + console.log(chalk.red(`Not enough balance to pay the ${selectedSTO} fee, Requires ${web3.utils.fromWei(transferAmount)} POLY but have ${web3.utils.fromWei(ownerBalance)} POLY. Access POLY faucet to get the POLY to complete this txn`)); console.log(chalk.red(`**************************************************************************************************************************************************\n`)); process.exit(0); } else { - let transferAction = polyToken.methods.transfer(securityToken._address, new BigNumber(transferAmount)); - let receipt = await common.sendTransaction(Issuer, transferAction, defaultGasPrice, 0, 1.5); + let transferAction = polyToken.methods.transfer(securityToken._address, transferAmount); + let receipt = await common.sendTransaction(Issuer, transferAction, defaultGasPrice, 0, 2); let event = common.getEventFromLogs(polyToken._jsonInterface, receipt.logs, 'Transfer'); console.log(`Number of POLY sent: ${web3.utils.fromWei(new web3.utils.BN(event._value))}`) } @@ -1017,7 +1021,7 @@ async function usdTieredSTO_configure() { await common.sendTransaction(Issuer, changeAccreditedAction, defaultGasPrice); break; case 2: - shell.exec(`${__dirname}/scripts/script.sh Accredit ${tokenSymbol} 75`); + shell.exec(`${__dirname}/scripts/script.sh Accredit ${tokenSymbol} 75 ${network}`); break; case 3: let account = readlineSync.question('Enter the address to change non accredited limit: '); @@ -1029,7 +1033,7 @@ async function usdTieredSTO_configure() { await common.sendTransaction(Issuer, changeNonAccreditedLimitAction, defaultGasPrice); break; case 4: - shell.exec(`${__dirname}/scripts/script.sh NonAccreditedLimit ${tokenSymbol} 75`); + shell.exec(`${__dirname}/scripts/script.sh NonAccreditedLimit ${tokenSymbol} 75 ${network}`); break; case 5: await modfifyTimes(); diff --git a/CLI/commands/accredit.js b/CLI/commands/accredit.js index 7f0cc6a75..c4dbd78b6 100644 --- a/CLI/commands/accredit.js +++ b/CLI/commands/accredit.js @@ -33,6 +33,7 @@ let badData = new Array(); startScript(); async function startScript() { + if (remoteNetwork == 'undefined') remoteNetwork = undefined; await global.initialize(remoteNetwork); try { let securityTokenRegistryAddress = await contracts.securityTokenRegistry(); diff --git a/CLI/commands/changeNonAccreditedLimit.js b/CLI/commands/changeNonAccreditedLimit.js index 374093773..b1ececbc7 100644 --- a/CLI/commands/changeNonAccreditedLimit.js +++ b/CLI/commands/changeNonAccreditedLimit.js @@ -33,6 +33,7 @@ let badData = new Array(); startScript(); async function startScript() { + if (remoteNetwork == 'undefined') remoteNetwork = undefined; await global.initialize(remoteNetwork); try { let securityTokenRegistryAddress = await contracts.securityTokenRegistry(); diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index a757b78ef..c4f158cd6 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -194,24 +194,19 @@ async function mintTokens(address, amount){ if (await securityToken.methods.mintingFrozen().call()) { console.log(chalk.red("Minting is not possible - Minting has been permanently frozen by issuer")); } else { - let result = await securityToken.methods.getModulesByType(MODULES_TYPES.STO).call(); - if (result.length > 0) { - console.log(chalk.red("Minting is not possible - STO is attached to Security Token")); - } else { - await whitelistAddress(address); + await whitelistAddress(address); - try { - let mintAction = securityToken.methods.mint(address,web3.utils.toWei(amount)); - let receipt = await common.sendTransaction(Issuer, mintAction, defaultGasPrice); - let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'Transfer'); - console.log(` + try { + let mintAction = securityToken.methods.mint(address,web3.utils.toWei(amount)); + let receipt = await common.sendTransaction(Issuer, mintAction, defaultGasPrice); + let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'Transfer'); + console.log(` Minted ${web3.utils.fromWei(event.value)} tokens to account ${event.to}` - ); - } catch (err) { - console.log(err); - console.log(chalk.red("There was an error processing the transfer transaction. \n The most probable cause for this error is one of the involved accounts not being in the whitelist or under a lockup period.")); - } + ); + } catch (err) { + console.log(err); + console.log(chalk.red("There was an error processing the transfer transaction. \n The most probable cause for this error is one of the involved accounts not being in the whitelist or under a lockup period.")); } } } diff --git a/CLI/commands/investor_portal.js b/CLI/commands/investor_portal.js index e08378fd9..fd308138d 100644 --- a/CLI/commands/investor_portal.js +++ b/CLI/commands/investor_portal.js @@ -36,6 +36,7 @@ let STOAddress; // Global display variables let displayCanBuy; +let displayValidKYC; // Start Script async function executeApp(investorAddress, investorPrivKey, symbol, currency, amount, remoteNetwork) { @@ -192,14 +193,15 @@ async function showCappedSTOInfo() { } } + let now = Math.floor(Date.now()/1000); + await generalTransferManager.methods.whitelist(User.address).call({}, function(error, result){ displayCanBuy = result.canBuyFromSTO; + displayValidKYC = parseInt(result.expiryTime) > now; }); - let now = Math.floor(Date.now()/1000); let timeTitle; let timeRemaining; - if(now < displayStartTime){ timeTitle = "STO starts in: "; timeRemaining = displayStartTime - now; @@ -229,6 +231,9 @@ async function showCappedSTOInfo() { if(!displayCanBuy) { console.log(chalk.red(`Your address is not approved to participate in this token sale.\n`)); process.exit(0); + } else if (!displayValidKYC) { + console.log(chalk.red(`Your KYC is expired.\n`)); + process.exit(0); } else if (now < displayStartTime) { console.log(chalk.red(`The token sale has not yet started.\n`)); process.exit(0); @@ -252,8 +257,10 @@ async function showUserInfoForUSDTieredSTO() await generalTransferManager.methods.whitelist(User.address).call({}, function(error, result){ displayCanBuy = result.canBuyFromSTO; + displayValidKYC = parseInt(result.expiryTime) > Math.floor(Date.now()/1000); }); - console.log(` - Whitelisted: ${(displayCanBuy)? 'YES' : 'NO'}`) + console.log(` - Whitelisted: ${(displayCanBuy)? 'YES' : 'NO'}`); + console.log(` - Valid KYC: ${(displayValidKYC)? 'YES' : 'NO'}`); let displayIsUserAccredited = await currentSTO.methods.accredited(User.address).call(); console.log(` - Accredited: ${(displayIsUserAccredited)? "YES" : "NO"}`) @@ -382,6 +389,9 @@ async function showUSDTieredSTOInfo() { if (!displayCanBuy) { console.log(chalk.red(`Your address is not approved to participate in this token sale.\n`)); process.exit(0); + } else if (!displayValidKYC) { + console.log(chalk.red(`Your KYC is expired.\n`)); + process.exit(0); } else if (now < displayStartTime) { console.log(chalk.red(`The token sale has not yet started.\n`)); process.exit(0); diff --git a/CLI/commands/module_manager.js b/CLI/commands/module_manager.js index b351a475d..2360e39dc 100644 --- a/CLI/commands/module_manager.js +++ b/CLI/commands/module_manager.js @@ -385,11 +385,6 @@ async function mintTokens() { console.log(chalk.red("Minting is not possible - Minting has been permanently frozen by issuer")); return; } - let stoModules = await securityToken.methods.getModulesByType(STO_KEY).call(); - if (stoModules.length > 0) { - console.log(chalk.red("Minting is not possible - STO is attached to Security Token")); - return; - } let _investor = readlineSync.question(chalk.yellow(`Enter the address to receive the tokens: `)); let _amount = readlineSync.question(chalk.yellow(`Enter the amount of tokens to mint: `)); diff --git a/CLI/commands/multi_mint.js b/CLI/commands/multi_mint.js index 736981789..0b7c272ca 100644 --- a/CLI/commands/multi_mint.js +++ b/CLI/commands/multi_mint.js @@ -35,6 +35,7 @@ let badData = new Array(); startScript(); async function startScript() { + if (remoteNetwork == 'undefined') remoteNetwork = undefined; await global.initialize(remoteNetwork); try { @@ -133,6 +134,7 @@ function readFile() { `); let affiliatesFailedArray = []; + let affiliatesKYCInvalidArray = []; //this for loop will do the batches, so it should run 75, 75, 50 with 200 for (let i = 0; i < distribData.length; i++) { try { @@ -142,12 +144,20 @@ function readFile() { for (let j = 0; j < distribData[i].length; j++) { let investorAccount = distribData[i][j][0]; let tokenAmount = web3.utils.toWei((distribData[i][j][1]).toString(),"ether"); - let verifiedTransaction = await securityToken.methods.verifyTransfer("0x0000000000000000000000000000000000000000", investorAccount, tokenAmount, web3.utils.fromAscii("")).call(); + let verifiedTransaction = await securityToken.methods.verifyTransfer("0x0000000000000000000000000000000000000000", investorAccount, tokenAmount, web3.utils.fromAscii('')).call(); if (verifiedTransaction) { affiliatesVerifiedArray.push(investorAccount); tokensVerifiedArray.push(tokenAmount); } else { - affiliatesFailedArray.push(investorAccount); + let gtmModule = await securityToken.methods.getModulesByName(web3.utils.toHex('GeneralTransferManager')).call(); + let generalTransferManagerABI = abis.generalTransferManager(); + let generalTransferManager = new web3.eth.Contract(generalTransferManagerABI, gtmModule[0]); + let validKYC = (await generalTransferManager.methods.whitelist(Issuer.address).call()).expiryTime > Math.floor(Date.now()/1000); + if (validKYC) { + affiliatesFailedArray.push(investorAccount); + } else { + affiliatesKYCInvalidArray.push(investorAccount); + } } } let mintMultiAction = securityToken.methods.mintMulti(affiliatesVerifiedArray, tokensVerifiedArray); @@ -213,9 +223,10 @@ function readFile() { console.log(`******************** EVENT LOGS ANALYSIS COMPLETE ********************\n`); console.log(`A total of ${totalInvestors} affiliated investors get the token\n`); - console.log(`This script in total sent ${fullFileData.length - badData.length - affiliatesFailedArray.length} new investors and updated investors to the blockchain.\n`); + console.log(`This script in total sent ${fullFileData.length - badData.length - affiliatesFailedArray.length - affiliatesKYCInvalidArray.length} new investors and updated investors to the blockchain.\n`); console.log(`There were ${badData.length} bad entries that didnt get sent to the blockchain in the script.\n`); - console.log(`There were ${affiliatesFailedArray.length} accounts that didnt get sent to the blockchain as they would fail.\n`); + console.log(`There were ${affiliatesKYCInvalidArray.length} accounts with invalid KYC.\n`); + console.log(`There were ${affiliatesFailedArray.length} accounts that didn't get sent to the blockchain as they would fail.\n`); console.log("************************************************************************************************"); console.log("OBJECT WITH EVERY USER AND THEIR MINTED TOKEN: \n\n", investorObjectLookup) @@ -224,27 +235,36 @@ function readFile() { let missingDistribs = []; let failedVerificationDistribs = []; + let invalidKYCDistribs = []; for (let l = 0; l < fullFileData.length; l++) { - if (affiliatesFailedArray.includes(fullFileData[l][0])) { + if (affiliatesKYCInvalidArray.includes(fullFileData[l][0])) { + invalidKYCDistribs.push(fullFileData[l]); + } else if (affiliatesFailedArray.includes(fullFileData[l][0])) { failedVerificationDistribs.push(fullFileData[l]); } else if (!investorObjectLookup.hasOwnProperty(fullFileData[l][0])) { missingDistribs.push(fullFileData[l]); } } + if (invalidKYCDistribs.length > 0) { + console.log("**************************************************************************************************************************"); + console.log("The following data arrays have an invalid KYC. Please review if these accounts are whitelisted and their KYC is not expired\n"); + console.log(invalidKYCDistribs); + console.log("**************************************************************************************************************************"); + } if (failedVerificationDistribs.length > 0) { - console.log("************************************************************************************************"); + console.log("*********************************************************************************************************"); console.log("-- The following data arrays failed at verifyTransfer. Please review if these accounts are whitelisted --\n"); console.log(failedVerificationDistribs); - console.log("************************************************************************************************"); + console.log("*********************************************************************************************************"); } if (missingDistribs.length > 0) { - console.log("************************************************************************************************"); - console.log("-- No Minted event was found for the following data arrays. Please review them manually --"); + console.log("******************************************************************************************"); + console.log("-- No Minted event was found for the following data arrays. Please review them manually --\n"); console.log(missingDistribs); - console.log("************************************************************************************************"); + console.log("******************************************************************************************"); } - if (missingDistribs.length == 0 && failedVerificationDistribs.length == 0) { + if (missingDistribs.length == 0 && failedVerificationDistribs.length == 0 && invalidKYCDistribs.length == 0) { console.log("\n**************************************************************************************************************************"); console.log("All accounts passed through from the CSV were successfully get the tokens, because we were able to read them all from events"); console.log("****************************************************************************************************************************"); diff --git a/CLI/commands/scripts/script.sh b/CLI/commands/scripts/script.sh index 1a88207fe..2ee363a8f 100755 --- a/CLI/commands/scripts/script.sh +++ b/CLI/commands/scripts/script.sh @@ -3,17 +3,17 @@ if [ $1 = "Whitelist" ]; then echo "Running the $1 script"; -node $PWD/CLI/commands/whitelist.js $2 $3 +node $PWD/CLI/commands/whitelist.js $2 $3 $4 elif [ $1 = "Multimint" ]; then echo "Running the $1 script"; -node $PWD/CLI/commands/multi_mint.js $2 $3 +node $PWD/CLI/commands/multi_mint.js $2 $3 $4 elif [ $1 = "Accredit" ]; then echo "Running the $1 script"; -node $PWD/CLI/commands/accredit.js $2 $3 +node $PWD/CLI/commands/accredit.js $2 $3 $4 elif [ $1 = "NonAccreditedLimit" ]; then echo "Running the $1 script"; -node $PWD/CLI/commands/changeNonAccreditedLimit.js $2 $3 +node $PWD/CLI/commands/changeNonAccreditedLimit.js $2 $3 $4 fi diff --git a/CLI/commands/whitelist.js b/CLI/commands/whitelist.js index 903ef40ec..4750adffa 100644 --- a/CLI/commands/whitelist.js +++ b/CLI/commands/whitelist.js @@ -32,6 +32,7 @@ const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); startScript(); async function startScript() { + if (remoteNetwork == 'undefined') remoteNetwork = undefined; await global.initialize(remoteNetwork); try { diff --git a/CLI/polymath-cli.js b/CLI/polymath-cli.js index a9c4d1dd9..5ce0a455d 100644 --- a/CLI/polymath-cli.js +++ b/CLI/polymath-cli.js @@ -91,7 +91,7 @@ program .alias('w') .description('Mass-update a whitelist of allowed/known investors') .action(async function(tokenSymbol, batchSize) { - shell.exec(`${__dirname}/commands/scripts/script.sh Whitelist ${tokenSymbol} ${batchSize} ${remoteNetwork} ${program.remoteNode}`); + shell.exec(`${__dirname}/commands/scripts/script.sh Whitelist ${tokenSymbol} ${batchSize} ${program.remoteNode}`); }); program From 5ed3fa47efbeb9d2a2c20184dc65c56ae9379391 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 05:06:39 +0530 Subject: [PATCH 121/142] Improved deploy info (#330) --- migrations/2_deploy_contracts.js | 41 +++++++++++++++----------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 7cd5bb528..0994e249e 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -293,32 +293,29 @@ module.exports = function (deployer, network, accounts) { }).then(() => { console.log('\n'); console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - ModuleRegistryProxy: ${ModuleRegistryProxy.address} - FeatureRegistry: ${FeatureRegistry.address} + ----------------------- Polymath Network Smart Contracts: ----------------------- + PolymathRegistry: ${PolymathRegistry.address} + SecurityTokenRegistry (Proxy): ${SecurityTokenRegistryProxy.address} + ModuleRegistry (Proxy): ${ModuleRegistryProxy.address} + FeatureRegistry: ${FeatureRegistry.address} - ETHOracle: ${ETHOracle} - POLYOracle: ${POLYOracle} + 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} - USDTieredSTOProxyFactory: ${USDTieredSTOProxyFactory.address} + CappedSTOFactory: ${CappedSTOFactory.address} + USDTieredSTOFactory: ${USDTieredSTOFactory.address} + USDTieredSTOProxyFactory: ${USDTieredSTOProxyFactory.address} - CountTransferManagerFactory: ${CountTransferManagerFactory.address} - PercentageTransferManagerFactory: ${PercentageTransferManagerFactory.address} - ManualApprovalTransferManagerFactory: - ${ManualApprovalTransferManagerFactory.address} - EtherDividendCheckpointFactory: ${EtherDividendCheckpointFactory.address} - ERC20DividendCheckpointFactory: ${ERC20DividendCheckpointFactory.address} - ----------------------------------------------------------------------------- + CountTransferManagerFactory: ${CountTransferManagerFactory.address} + PercentageTransferManagerFactory: ${PercentageTransferManagerFactory.address} + ManualApprovalTransferManagerFactory: ${ManualApprovalTransferManagerFactory.address} + EtherDividendCheckpointFactory: ${EtherDividendCheckpointFactory.address} + ERC20DividendCheckpointFactory: ${ERC20DividendCheckpointFactory.address} + --------------------------------------------------------------------------------- `); console.log('\n'); // -------- END OF POLYMATH NETWORK Configuration -------// From fde4d3006654329e7954a88999ddbccab35dea6b Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 09:50:52 +0530 Subject: [PATCH 122/142] Renamed VRTM module --- ...> LockupVolumeRestrictionTransferManager.sol} | 2 +- ...pVolumeRestrictionTransferManagerFactory.sol} | 12 ++++++------ test/helpers/createInstances.js | 4 ++-- ...ockup_volume_restriction_transfer_manager.js} | 16 +++++++++------- 4 files changed, 18 insertions(+), 16 deletions(-) rename contracts/modules/TransferManager/{VolumeRestrictionTransferManager.sol => LockupVolumeRestrictionTransferManager.sol} (99%) rename contracts/modules/TransferManager/{VolumeRestrictionTransferManagerFactory.sol => LockupVolumeRestrictionTransferManagerFactory.sol} (84%) rename test/{w_volume_restriction_transfer_manager.js => w_lockup_volume_restriction_transfer_manager.js} (98%) diff --git a/contracts/modules/TransferManager/VolumeRestrictionTransferManager.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol similarity index 99% rename from contracts/modules/TransferManager/VolumeRestrictionTransferManager.sol rename to contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol index e79bad1bc..59a8b53b0 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTransferManager.sol +++ b/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol @@ -4,7 +4,7 @@ import "./ITransferManager.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; -contract VolumeRestrictionTransferManager is ITransferManager { +contract LockupVolumeRestrictionTransferManager is ITransferManager { using SafeMath for uint256; diff --git a/contracts/modules/TransferManager/VolumeRestrictionTransferManagerFactory.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol similarity index 84% rename from contracts/modules/TransferManager/VolumeRestrictionTransferManagerFactory.sol rename to contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol index 81afdad4c..0bb34fce2 100644 --- a/contracts/modules/TransferManager/VolumeRestrictionTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol @@ -1,12 +1,12 @@ pragma solidity ^0.4.24; -import "./VolumeRestrictionTransferManager.sol"; +import "./LockupVolumeRestrictionTransferManager.sol"; import "../ModuleFactory.sol"; /** * @title Factory for deploying ManualApprovalTransferManager module */ -contract VolumeRestrictionTransferManagerFactory is ModuleFactory { +contract LockupVolumeRestrictionTransferManagerFactory is ModuleFactory { /** * @notice Constructor @@ -20,7 +20,7 @@ contract VolumeRestrictionTransferManagerFactory is ModuleFactory { { version = "1.0.0"; name = "VolumeRestrictionTransferManager"; - title = "Volume Restriction Transfer Manager"; + title = "Lockup Volume Restriction Transfer Manager"; description = "Manage transfers using lock ups over time"; compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); @@ -33,9 +33,9 @@ contract VolumeRestrictionTransferManagerFactory is ModuleFactory { function deploy(bytes /* _data */) external returns(address) { if (setupCost > 0) require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); - address volumeRestrictionTransferManager = new VolumeRestrictionTransferManager(msg.sender, address(polyToken)); - emit GenerateModuleFromFactory(address(volumeRestrictionTransferManager), getName(), address(this), msg.sender, now); - return address(volumeRestrictionTransferManager); + address lockupVolumeRestrictionTransferManager = new LockupVolumeRestrictionTransferManager(msg.sender, address(polyToken)); + emit GenerateModuleFromFactory(address(lockupVolumeRestrictionTransferManager), getName(), address(this), msg.sender, now); + return address(lockupVolumeRestrictionTransferManager); } /** diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index ff2a66f4b..3ca2f29d5 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -22,7 +22,7 @@ const STFactory = artifacts.require("./STFactory.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); -const VolumeRestrictionTransferManagerFactory = artifacts.require("./VolumeRestrictionTransferManagerFactory"); +const VolumeRestrictionTransferManagerFactory = artifacts.require("./LockupVolumeRestrictionTransferManagerFactory"); const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); const PolyToken = artifacts.require("./PolyToken.sol"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); @@ -237,7 +237,7 @@ export async function deployPercentageTMAndVerified(accountPolymath, MRProxyInst return new Array(I_PercentageTransferManagerFactory); } -export async function deployVolumeRTMAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { +export async function deployLockupVolumeRTMAndVerified(accountPolymath, MRProxyInstance, polyToken, setupCost) { I_VolumeRestrictionTransferManagerFactory = await VolumeRestrictionTransferManagerFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); assert.notEqual( I_VolumeRestrictionTransferManagerFactory.address.valueOf(), diff --git a/test/w_volume_restriction_transfer_manager.js b/test/w_lockup_volume_restriction_transfer_manager.js similarity index 98% rename from test/w_volume_restriction_transfer_manager.js rename to test/w_lockup_volume_restriction_transfer_manager.js index fdef2a0ae..a449ad780 100644 --- a/test/w_volume_restriction_transfer_manager.js +++ b/test/w_lockup_volume_restriction_transfer_manager.js @@ -2,19 +2,19 @@ import latestTime from './helpers/latestTime'; import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; import { encodeProxyCall } from './helpers/encodeCall'; -import { setUpPolymathNetwork, deployVolumeRTMAndVerified } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployLockupVolumeRTMAndVerified } from "./helpers/createInstances"; import { catchRevert } from "./helpers/exceptions"; const SecurityToken = artifacts.require('./SecurityToken.sol'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const VolumeRestrictionTransferManager = artifacts.require('./VolumeRestrictionTransferManager'); +const VolumeRestrictionTransferManager = artifacts.require('./LockupVolumeRestrictionTransferManager'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); const Web3 = require('web3'); const BigNumber = require('bignumber.js'); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port -contract('VolumeRestrictionTransferManager', accounts => { +contract('LockupVolumeRestrictionTransferManager', accounts => { // Accounts Variable declaration let account_polymath; @@ -95,9 +95,9 @@ contract('VolumeRestrictionTransferManager', accounts => { ] = instances; // STEP 4(c): Deploy the VolumeRestrictionTransferManager - [I_VolumeRestrictionTransferManagerFactory] = await deployVolumeRTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [I_VolumeRestrictionTransferManagerFactory] = await deployLockupVolumeRTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); // STEP 4(d): Deploy the VolumeRestrictionTransferManager - [P_VolumeRestrictionTransferManagerFactory] = await deployVolumeRTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); + [P_VolumeRestrictionTransferManagerFactory] = await deployLockupVolumeRTMAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); // Printing all the contract addresses console.log(` @@ -111,7 +111,9 @@ contract('VolumeRestrictionTransferManager', accounts => { STFactory: ${I_STFactory.address} GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - VolumeRestrictionTransferManagerFactory: ${I_VolumeRestrictionTransferManagerFactory.address} + + LockupVolumeRestrictionTransferManagerFactory: + ${I_VolumeRestrictionTransferManagerFactory.address} ----------------------------------------------------------------------------- `); }); @@ -779,7 +781,7 @@ contract('VolumeRestrictionTransferManager', accounts => { "Manage transfers using lock ups over time", "Wrong Module added"); assert.equal(await I_VolumeRestrictionTransferManagerFactory.getTitle.call(), - "Volume Restriction Transfer Manager", + "Lockup Volume Restriction Transfer Manager", "Wrong Module added"); assert.equal(await I_VolumeRestrictionTransferManagerFactory.getInstructions.call(), "Allows an issuer to set lockup periods for user addresses, with funds distributed over time. Init function takes no parameters.", From 9d09b701e582ac1d455fc349d0e0e8ba58ab458a Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 17:19:17 +0530 Subject: [PATCH 123/142] Limited faucet drops --- contracts/mocks/PolyTokenFaucet.sol | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/contracts/mocks/PolyTokenFaucet.sol b/contracts/mocks/PolyTokenFaucet.sol index aa106bf0e..8298d39f9 100644 --- a/contracts/mocks/PolyTokenFaucet.sol +++ b/contracts/mocks/PolyTokenFaucet.sol @@ -10,7 +10,7 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; contract PolyTokenFaucet { using SafeMath for uint256; - uint256 totalSupply_ = 1000000; + uint256 totalSupply_; string public name = "Polymath Network"; uint8 public decimals = 18; string public symbol = "POLY"; @@ -21,10 +21,18 @@ contract PolyTokenFaucet { event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); + constructor() public { + totalSupply_ = 1000000; + balances[msg.sender] = 1000000; + emit Transfer(address(0), msg.sender, 1000000); + } + /* Token faucet - Not part of the ERC20 standard */ function getTokens(uint256 _amount, address _recipient) public returns (bool) { - balances[_recipient] += _amount; - totalSupply_ += _amount; + require(_amount <= 1000000); + require(_recipient != address(0)); + balances[_recipient] = balances[_recipient].add(_amount); + totalSupply_ = totalSupply_.add(_amount); emit Transfer(address(0), _recipient, _amount); return true; } From ede272b998a92587f57296dfc798be7232b2d9ee Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 17:26:42 +0530 Subject: [PATCH 124/142] Faucet decimal fixed --- contracts/mocks/PolyTokenFaucet.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/mocks/PolyTokenFaucet.sol b/contracts/mocks/PolyTokenFaucet.sol index 8298d39f9..b4fcd9e7b 100644 --- a/contracts/mocks/PolyTokenFaucet.sol +++ b/contracts/mocks/PolyTokenFaucet.sol @@ -29,8 +29,8 @@ contract PolyTokenFaucet { /* Token faucet - Not part of the ERC20 standard */ function getTokens(uint256 _amount, address _recipient) public returns (bool) { - require(_amount <= 1000000); - require(_recipient != address(0)); + require(_amount <= 1000000 * uint256(10)**18, "Amount can not be more than 1 million"); + require(_recipient != address(0), "Recipient address can not be empty"); balances[_recipient] = balances[_recipient].add(_amount); totalSupply_ = totalSupply_.add(_amount); emit Transfer(address(0), _recipient, _amount); From 57026c17b34aff40b9bdd0aaaed00a9e555500cd Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 17:52:01 +0530 Subject: [PATCH 125/142] Renamed TransferManager to TM --- ...nTransferManager.sol => LockupVolumeRestrictionTM.sol} | 2 +- ...erFactory.sol => LockupVolumeRestrictionTMFactory.sol} | 8 ++++---- ...tionManager.sol => SingleTradeVolumeRestrictionTM.sol} | 2 +- ...tory.sol => SingleTradeVolumeRestrictionTMFactory.sol} | 8 ++++---- test/helpers/createInstances.js | 4 ++-- test/w_lockup_volume_restriction_transfer_manager.js | 2 +- test/x_single_trade_volume_restriction.js | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) rename contracts/modules/TransferManager/{LockupVolumeRestrictionTransferManager.sol => LockupVolumeRestrictionTM.sol} (99%) rename contracts/modules/TransferManager/{LockupVolumeRestrictionTransferManagerFactory.sol => LockupVolumeRestrictionTMFactory.sol} (90%) rename contracts/modules/TransferManager/{SingleTradeVolumeRestrictionManager.sol => SingleTradeVolumeRestrictionTM.sol} (99%) rename contracts/modules/TransferManager/{SingleTradeVolumeRestrictionManagerFactory.sol => SingleTradeVolumeRestrictionTMFactory.sol} (91%) diff --git a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTM.sol similarity index 99% rename from contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol rename to contracts/modules/TransferManager/LockupVolumeRestrictionTM.sol index 59a8b53b0..bc9606e79 100644 --- a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol +++ b/contracts/modules/TransferManager/LockupVolumeRestrictionTM.sol @@ -4,7 +4,7 @@ import "./ITransferManager.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; -contract LockupVolumeRestrictionTransferManager is ITransferManager { +contract LockupVolumeRestrictionTM is ITransferManager { using SafeMath for uint256; diff --git a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTMFactory.sol similarity index 90% rename from contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol rename to contracts/modules/TransferManager/LockupVolumeRestrictionTMFactory.sol index 0bb34fce2..307390138 100644 --- a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/LockupVolumeRestrictionTMFactory.sol @@ -1,12 +1,12 @@ pragma solidity ^0.4.24; -import "./LockupVolumeRestrictionTransferManager.sol"; +import "./LockupVolumeRestrictionTM.sol"; import "../ModuleFactory.sol"; /** * @title Factory for deploying ManualApprovalTransferManager module */ -contract LockupVolumeRestrictionTransferManagerFactory is ModuleFactory { +contract LockupVolumeRestrictionTMFactory is ModuleFactory { /** * @notice Constructor @@ -19,7 +19,7 @@ contract LockupVolumeRestrictionTransferManagerFactory is ModuleFactory { ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { version = "1.0.0"; - name = "VolumeRestrictionTransferManager"; + name = "LockupVolumeRestrictionTM"; title = "Lockup Volume Restriction Transfer Manager"; description = "Manage transfers using lock ups over time"; compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); @@ -33,7 +33,7 @@ contract LockupVolumeRestrictionTransferManagerFactory is ModuleFactory { function deploy(bytes /* _data */) external returns(address) { if (setupCost > 0) require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); - address lockupVolumeRestrictionTransferManager = new LockupVolumeRestrictionTransferManager(msg.sender, address(polyToken)); + LockupVolumeRestrictionTM lockupVolumeRestrictionTransferManager = new LockupVolumeRestrictionTM(msg.sender, address(polyToken)); emit GenerateModuleFromFactory(address(lockupVolumeRestrictionTransferManager), getName(), address(this), msg.sender, now); return address(lockupVolumeRestrictionTransferManager); } diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTM.sol similarity index 99% rename from contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol rename to contracts/modules/TransferManager/SingleTradeVolumeRestrictionTM.sol index 04c4e8f99..2f507f1a6 100644 --- a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManager.sol +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTM.sol @@ -6,7 +6,7 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; * @title Transfer Manager for limiting volume of tokens in a single trade */ -contract SingleTradeVolumeRestrictionManager is ITransferManager { +contract SingleTradeVolumeRestrictionTM is ITransferManager { using SafeMath for uint256; bytes32 constant public ADMIN = "ADMIN"; diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTMFactory.sol similarity index 91% rename from contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol rename to contracts/modules/TransferManager/SingleTradeVolumeRestrictionTMFactory.sol index 4233d0788..7b5c47ffb 100644 --- a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionManagerFactory.sol +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTMFactory.sol @@ -1,12 +1,12 @@ pragma solidity ^0.4.24; import "./../ModuleFactory.sol"; -import "./SingleTradeVolumeRestrictionManager.sol"; +import "./SingleTradeVolumeRestrictionTM.sol"; import "../../libraries/Util.sol"; /** * @title Factory for deploying SingleTradeVolumeRestrictionManager */ -contract SingleTradeVolumeRestrictionManagerFactory is ModuleFactory { +contract SingleTradeVolumeRestrictionTMFactory is ModuleFactory { /** @@ -20,7 +20,7 @@ contract SingleTradeVolumeRestrictionManagerFactory is ModuleFactory { ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { version = "1.0.0"; - name = "SingleTradeVolumeRestriction"; + name = "SingleTradeVolumeRestrictionTM"; title = "Single Trade Volume Restriction Manager"; description = "Imposes volume restriction on a single trade"; compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); @@ -34,7 +34,7 @@ contract SingleTradeVolumeRestrictionManagerFactory is ModuleFactory { function deploy(bytes _data) external returns(address) { if (setupCost > 0) require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); - SingleTradeVolumeRestrictionManager singleTradeVolumeRestrictionManager = new SingleTradeVolumeRestrictionManager(msg.sender, address(polyToken)); + SingleTradeVolumeRestrictionTM singleTradeVolumeRestrictionManager = new SingleTradeVolumeRestrictionTM(msg.sender, address(polyToken)); require(Util.getSig(_data) == singleTradeVolumeRestrictionManager.getInitFunction(), "Provided data is not valid"); require(address(singleTradeVolumeRestrictionManager).call(_data), "Un-successfull call"); diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 3ca2f29d5..82a77e42a 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -11,7 +11,7 @@ const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpointFactory.sol"); const EtherDividendCheckpointFactory = artifacts.require("./EtherDividendCheckpointFactory.sol"); const ManualApprovalTransferManagerFactory = artifacts.require("./ManualApprovalTransferManagerFactory.sol"); -const SingleTradeVolumeRestrictionManagerFactory = artifacts.require('./SingleTradeVolumeRestrictionManagerFactory.sol'); +const SingleTradeVolumeRestrictionManagerFactory = artifacts.require('./SingleTradeVolumeRestrictionTMFactory.sol'); const TrackedRedemptionFactory = artifacts.require("./TrackedRedemptionFactory.sol"); const PercentageTransferManagerFactory = artifacts.require("./PercentageTransferManagerFactory.sol"); const USDTieredSTOFactory = artifacts.require("./USDTieredSTOFactory.sol"); @@ -22,7 +22,7 @@ const STFactory = artifacts.require("./STFactory.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const CountTransferManagerFactory = artifacts.require("./CountTransferManagerFactory.sol"); -const VolumeRestrictionTransferManagerFactory = artifacts.require("./LockupVolumeRestrictionTransferManagerFactory"); +const VolumeRestrictionTransferManagerFactory = artifacts.require("./LockupVolumeRestrictionTMFactory"); const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); const PolyToken = artifacts.require("./PolyToken.sol"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); diff --git a/test/w_lockup_volume_restriction_transfer_manager.js b/test/w_lockup_volume_restriction_transfer_manager.js index a449ad780..7d6feecf3 100644 --- a/test/w_lockup_volume_restriction_transfer_manager.js +++ b/test/w_lockup_volume_restriction_transfer_manager.js @@ -7,7 +7,7 @@ import { catchRevert } from "./helpers/exceptions"; const SecurityToken = artifacts.require('./SecurityToken.sol'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const VolumeRestrictionTransferManager = artifacts.require('./LockupVolumeRestrictionTransferManager'); +const VolumeRestrictionTransferManager = artifacts.require('./LockupVolumeRestrictionTM'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); const Web3 = require('web3'); diff --git a/test/x_single_trade_volume_restriction.js b/test/x_single_trade_volume_restriction.js index f21803e10..6b766695b 100644 --- a/test/x_single_trade_volume_restriction.js +++ b/test/x_single_trade_volume_restriction.js @@ -8,7 +8,7 @@ import { catchRevert } from "./helpers/exceptions"; const SecurityToken = artifacts.require('./SecurityToken.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const SingleTradeVolumeRestrictionManager = artifacts.require('./SingleTradeVolumeRestrictionManager'); +const SingleTradeVolumeRestrictionManager = artifacts.require('./SingleTradeVolumeRestrictionTM'); const CountTransferManagerFactory = artifacts.require('./CountTransferManagerFactory.sol'); const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); From 6b2e7ef3ac2b9d9c758be4ffac72c00c1b33d5ff Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 18:09:22 +0530 Subject: [PATCH 126/142] tests fixed --- test/w_lockup_volume_restriction_transfer_manager.js | 6 +++--- test/x_single_trade_volume_restriction.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/w_lockup_volume_restriction_transfer_manager.js b/test/w_lockup_volume_restriction_transfer_manager.js index 7d6feecf3..1caea7374 100644 --- a/test/w_lockup_volume_restriction_transfer_manager.js +++ b/test/w_lockup_volume_restriction_transfer_manager.js @@ -223,7 +223,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), - "VolumeRestrictionTransferManager", + "LockupVolumeRestrictionTM", "VolumeRestrictionTransferManagerFactory module was not added" ); P_VolumeRestrictionTransferManager = VolumeRestrictionTransferManager.at(tx.logs[3].args._module); @@ -236,7 +236,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), - "VolumeRestrictionTransferManager", + "LockupVolumeRestrictionTM", "VolumeRestrictionTransferManager module was not added" ); I_VolumeRestrictionTransferManager = VolumeRestrictionTransferManager.at(tx.logs[2].args._module); @@ -775,7 +775,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { assert.equal((await I_VolumeRestrictionTransferManagerFactory.getTypes.call())[0],2); assert.equal(web3.utils.toAscii(await I_VolumeRestrictionTransferManagerFactory.getName.call()) .replace(/\u0000/g, ''), - "VolumeRestrictionTransferManager", + "LockupVolumeRestrictionTM", "Wrong Module added"); assert.equal(await I_VolumeRestrictionTransferManagerFactory.getDescription.call(), "Manage transfers using lock ups over time", diff --git a/test/x_single_trade_volume_restriction.js b/test/x_single_trade_volume_restriction.js index 6b766695b..f4bf8180a 100644 --- a/test/x_single_trade_volume_restriction.js +++ b/test/x_single_trade_volume_restriction.js @@ -231,7 +231,7 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal( web3.utils.toAscii(tx.logs[3].args._name) .replace(/\u0000/g, ''), - "SingleTradeVolumeRestriction", + "SingleTradeVolumeRestrictionTM", "SingleTradeVolumeRestrictionManagerFactory module was not added" ); P_SingleTradeVolumeRestrictionManager = SingleTradeVolumeRestrictionManager.at(tx.logs[3].args._module); @@ -246,7 +246,7 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), - "SingleTradeVolumeRestriction", + "SingleTradeVolumeRestrictionTM", "SingleTradeVolumeRestriction module was not added" ); I_SingleTradeVolumeRestrictionManager = SingleTradeVolumeRestrictionManager.at(tx.logs[2].args._module); @@ -261,7 +261,7 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal( web3.utils.toAscii(tx.logs[2].args._name) .replace(/\u0000/g, ''), - "SingleTradeVolumeRestriction", + "SingleTradeVolumeRestrictionTM", "SingleTradeVolumeRestriction module was not added" ); I_SingleTradeVolumeRestrictionPercentageManager = SingleTradeVolumeRestrictionManager.at(tx.logs[2].args._module); @@ -694,7 +694,7 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { assert.equal(await I_SingleTradeVolumeRestrictionManagerFactory.setupCost.call(), 0); assert.equal((await I_SingleTradeVolumeRestrictionManagerFactory.getTypes.call())[0], 2); let name = web3.utils.toUtf8(await I_SingleTradeVolumeRestrictionManagerFactory.getName.call()); - assert.equal(name, "SingleTradeVolumeRestriction", "Wrong Module added"); + assert.equal(name, "SingleTradeVolumeRestrictionTM", "Wrong Module added"); let desc = await I_SingleTradeVolumeRestrictionManagerFactory.getDescription.call(); assert.equal(desc, "Imposes volume restriction on a single trade", "Wrong Module added"); let title = await I_SingleTradeVolumeRestrictionManagerFactory.getTitle.call(); From 5e5a1456184129944b4ef10d412f681070369715 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 18:46:49 +0530 Subject: [PATCH 127/142] Using decimals --- contracts/mocks/PolyTokenFaucet.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/mocks/PolyTokenFaucet.sol b/contracts/mocks/PolyTokenFaucet.sol index b4fcd9e7b..853ead229 100644 --- a/contracts/mocks/PolyTokenFaucet.sol +++ b/contracts/mocks/PolyTokenFaucet.sol @@ -12,7 +12,7 @@ contract PolyTokenFaucet { using SafeMath for uint256; uint256 totalSupply_; string public name = "Polymath Network"; - uint8 public decimals = 18; + uint8 public decimals; string public symbol = "POLY"; mapping(address => uint256) balances; @@ -23,13 +23,14 @@ contract PolyTokenFaucet { constructor() public { totalSupply_ = 1000000; + decimals = 18; balances[msg.sender] = 1000000; emit Transfer(address(0), msg.sender, 1000000); } /* Token faucet - Not part of the ERC20 standard */ function getTokens(uint256 _amount, address _recipient) public returns (bool) { - require(_amount <= 1000000 * uint256(10)**18, "Amount can not be more than 1 million"); + require(_amount <= 1000000 * uint256(10)**decimals, "Amount can not be more than 1 million"); require(_recipient != address(0), "Recipient address can not be empty"); balances[_recipient] = balances[_recipient].add(_amount); totalSupply_ = totalSupply_.add(_amount); From 94b5c7d1e67e6e9596310d3361bbcd4cba5a2da1 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 11 Oct 2018 19:13:15 +0530 Subject: [PATCH 128/142] Increased initial minting --- contracts/mocks/PolyTokenFaucet.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/mocks/PolyTokenFaucet.sol b/contracts/mocks/PolyTokenFaucet.sol index 853ead229..4a30fe861 100644 --- a/contracts/mocks/PolyTokenFaucet.sol +++ b/contracts/mocks/PolyTokenFaucet.sol @@ -22,10 +22,10 @@ contract PolyTokenFaucet { event Approval(address indexed _owner, address indexed _spender, uint256 _value); constructor() public { - totalSupply_ = 1000000; decimals = 18; - balances[msg.sender] = 1000000; - emit Transfer(address(0), msg.sender, 1000000); + totalSupply_ = 1000000 * uint256(10)**decimals; + balances[msg.sender] = totalSupply_; + emit Transfer(address(0), msg.sender, totalSupply_); } /* Token faucet - Not part of the ERC20 standard */ From 49aae2bcbe1c7ac7ad010b0077485e83b14f0800 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Thu, 11 Oct 2018 11:10:52 -0300 Subject: [PATCH 129/142] Revert "Voting module" (#336) Reverting this merge so we can complete documentation, improve tests and build the CLI before merging it. Also, so it's actually merged to 2.x and not to 1.5.0/2.0.0. --- .../Checkpoint/WeightedVoteCheckpoint.sol | 141 ----- .../WeightedVoteCheckpointFactory.sol | 98 ---- test/g_general_permission_manager.js | 405 +++++-------- test/x_weighted_vote_checkpoint.js | 536 ------------------ 4 files changed, 143 insertions(+), 1037 deletions(-) delete mode 100644 contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol delete mode 100644 contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol delete mode 100644 test/x_weighted_vote_checkpoint.js diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol deleted file mode 100644 index 70acd5a19..000000000 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpoint.sol +++ /dev/null @@ -1,141 +0,0 @@ -pragma solidity ^0.4.24; - -import "./ICheckpoint.sol"; -import "../Module.sol"; -import "openzeppelin-solidity/contracts/math/SafeMath.sol"; - -/** - * @title Checkpoint module for token weighted vote - * @notice This voting system uses public votes - */ -contract WeightedVoteCheckpoint is ICheckpoint, Module { - using SafeMath for uint256; - - struct Ballot { - uint256 checkpointId; - uint256 totalSupply; - uint256 startTime; - uint256 endTime; - uint256 cumulativeYes; - uint256 cumulativeNo; - uint256 numVotes; - mapping(address => Vote) voteByAddress; - bool isActive; - } - - Ballot[] public ballots; - - struct Vote { - uint256 time; - uint256 weight; - bool vote; - } - - event BallotCreated(uint256 _startTime, uint256 _endTime, uint256 _ballotId, uint256 _checkpointId); - event VoteCasted(uint256 _ballotId, uint256 _time, address indexed _investor, uint256 _weight, bool _vote); - event BallotActiveStatsChanged(uint256 _ballotId, bool _isActive); - - /** - * @notice Constructor - * @param _securityToken Address of the security token - * @param _polyAddress Address of the polytoken - */ - constructor(address _securityToken, address _polyAddress) public Module(_securityToken, _polyAddress) { - - } - - /** - * @notice Queries the result of a given ballot - * @param _ballotId Id of the target ballot - * @return uint256 cummulativeYes - * @return uint256 cummulativeNo - * @return uint256 totalAbstain - * @return uint256 remainingTime - */ - function getResults(uint256 _ballotId) public view returns (uint256 cummulativeYes, uint256 cummulativeNo, uint256 totalAbstain, uint256 remainingTime) { - uint256 abstain = (ballots[_ballotId].totalSupply.sub(ballots[_ballotId].cumulativeYes)).sub(ballots[_ballotId].cumulativeNo); - uint256 time = (ballots[_ballotId].endTime > now) ? ballots[_ballotId].endTime.sub(now) : 0; - return (ballots[_ballotId].cumulativeYes, ballots[_ballotId].cumulativeNo, abstain, time); - } - - /** - * @notice Allows a token holder to cast their vote on a specific ballot - * @param _vote The vote (true/false) in favor or against the proposal - * @param _ballotId The index of the target ballot - * @return bool success - */ - function castVote(bool _vote, uint256 _ballotId) public returns (bool) { - require(now > ballots[_ballotId].startTime && now < ballots[_ballotId].endTime, "Voting period is not active."); - require(ballots[_ballotId].voteByAddress[msg.sender].time == 0, "Token holder has already voted."); - require(ballots[_ballotId].isActive == true, "This ballot is deactiveated."); - uint256 checkpointId = ballots[_ballotId].checkpointId; - uint256 weight = ISecurityToken(securityToken).balanceOfAt(msg.sender,checkpointId); - require(weight > 0, "Token Holder balance is zero."); - ballots[_ballotId].voteByAddress[msg.sender].time = now; - ballots[_ballotId].voteByAddress[msg.sender].weight = weight; - ballots[_ballotId].voteByAddress[msg.sender].vote = _vote; - ballots[_ballotId].numVotes = ballots[_ballotId].numVotes.add(1); - if (_vote == true) { - ballots[_ballotId].cumulativeYes = ballots[_ballotId].cumulativeYes.add(weight); - } else { - ballots[_ballotId].cumulativeNo = ballots[_ballotId].cumulativeNo.add(weight); - } - emit VoteCasted(_ballotId, now, msg.sender, weight, _vote); - return true; - } - - /** - * @notice Allows the token issuer to create a ballot - * @param _duration The duration of the voting period in seconds - * @return bool success - */ - function createBallot(uint256 _duration) public onlyOwner { - require(_duration > 0, "Incorrect ballot duration."); - uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); - uint256 endTime = now.add(_duration); - createCustomBallot(now, endTime, checkpointId); - } - - /** - * @notice Allows the token issuer to create a ballot with custom settings - * @param _startTime Start time of the voting period in Unix Epoch time - * @param _endTime End time of the voting period in Unix Epoch time - * @param _checkpointId Index of the checkpoint to use for token balances - * @return bool success - */ - function createCustomBallot(uint256 _startTime, uint256 _endTime, uint256 _checkpointId) public onlyOwner { - require(_endTime > _startTime, "Ballot end time must be later than start time."); - uint256 ballotId = ballots.length; - uint256 supplyAtCheckpoint = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); - ballots.push(Ballot(_checkpointId,supplyAtCheckpoint,_startTime,_endTime,0,0,0, true)); - emit BallotCreated(_startTime, _endTime, ballotId, _checkpointId); - } - - /** - * @notice Allows the token issuer to set the active stats of a ballot - * @param _ballotId The index of the target ballot - * @param _isActive The bool value of the active stats of the ballot - * @return bool success - */ - function setActiveStatsBallot(uint256 _ballotId, bool _isActive) public onlyOwner { - require(now < ballots[_ballotId].endTime, "This ballot has already ended."); - require(ballots[_ballotId].isActive != _isActive, "Active state unchanged"); - ballots[_ballotId].isActive = _isActive; - emit BallotActiveStatsChanged(_ballotId, _isActive); - } - - - function getInitFunction() public returns(bytes4) { - return bytes4(0); - } - - /** - * @notice Return the permissions flag that are associated with STO - * @return bytes32 array - */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](0); - return allPermissions; - } - -} diff --git a/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol b/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol deleted file mode 100644 index 6fcf9b2d9..000000000 --- a/contracts/modules/Checkpoint/WeightedVoteCheckpointFactory.sol +++ /dev/null @@ -1,98 +0,0 @@ -pragma solidity ^0.4.24; - -import "./WeightedVoteCheckpoint.sol"; -import "../ModuleFactory.sol"; - -/** - * @title Factory for deploying WeightedVoteCheckpoint module - */ -contract WeightedVoteCheckpointFactory is ModuleFactory { - - /** - * @notice Constructor - * @param _polyAddress Address of the polytoken - * @param _setupCost Setup cost of the module - * @param _usageCost Usage cost of the module - * @param _subscriptionCost Subscription cost of the module - */ - constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public - ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { - version = "1.0.0"; - name = "WeightedVoteCheckpoint"; - title = "Weighted Vote Checkpoint"; - description = "Weighted votes based on token amount"; - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - - } - - /** - * @notice used to launch the Module with the help of factory - * @return address Contract address of the Module - */ - function deploy(bytes /* _data */) external returns(address) { - if (setupCost > 0) - require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); - return address(new WeightedVoteCheckpoint(msg.sender, address(polyToken))); - } - - /** - * @notice Type of the Module factory - */ - function getTypes() external view returns(uint8[]) { - uint8[] memory res = new uint8[](1); - res[0] = 4; - return res; - } - - /** - * @notice Get the name of the Module - */ - function getName() public view returns(bytes32) { - return name; - } - - /** - * @notice Get the description of the Module - */ - function getDescription() external view returns(string) { - return description; - } - - /** - * @notice Get the title of the Module - */ - function getTitle() external view returns(string) { - return title; - } - - /** - * @notice Get the version of the Module - */ - function getVersion() external view returns(string) { - return version; - } - - /** - * @notice Get the setup cost of the module - */ - function getSetupCost() external view returns (uint256) { - return setupCost; - } - - /** - * @notice Get the Instructions that helped to used the module - */ - function getInstructions() external view returns(string) { - return "Create a vote which allows token holders to vote on an issue with a weight proportional to their balances at the point the vote is created."; - } - - /** - * @notice Get the tags related to the module factory - */ - function getTags() external view returns(bytes32[]) { - bytes32[] memory availableTags = new bytes32[](0); - return availableTags; - } -} diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index b04f8a18d..0cf090030 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -1,32 +1,22 @@ -import latestTime from './helpers/latestTime'; -import {signData} from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); -const DummySTO = artifacts.require('./DummySTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('GeneralPermissionManager', accounts => { - +import latestTime from "./helpers/latestTime"; +import { signData } from "./helpers/signData"; +import { pk } from "./helpers/testprivateKey"; +import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; +import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; +import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import { catchRevert } from "./helpers/exceptions"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed } from "./helpers/createInstances"; + +const DummySTO = artifacts.require("./DummySTO.sol"); +const SecurityToken = artifacts.require("./SecurityToken.sol"); +const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); +const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); + +const Web3 = require("web3"); +const BigNumber = require("bignumber.js"); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port + +contract("GeneralPermissionManager", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -84,17 +74,15 @@ contract('GeneralPermissionManager', accounts => { const initRegFee = web3.utils.toWei("250"); // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); + const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time + const endTime = startTime + duration.days(80); // Add 80 days more + const cap = web3.utils.toWei("10", "ether"); const someString = "A string which is not used"; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; + const STOParameters = ["uint256", "uint256", "uint256", "string"]; let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); - before(async() => { + before(async () => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -108,149 +96,54 @@ contract('GeneralPermissionManager', accounts => { account_delegate2 = accounts[6]; account_delegate3 = accounts[5]; - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); + // Step 1: Deploy the genral PM ecosystem + let instances = await setUpPolymathNetwork(account_polymath, token_owner); + + [ + I_PolymathRegistry, + I_PolyToken, + I_FeatureRegistry, + I_ModuleRegistry, + I_ModuleRegistryProxy, + I_MRProxied, + I_GeneralTransferManagerFactory, + I_STFactory, + I_SecurityTokenRegistry, + I_SecurityTokenRegistryProxy, + I_STRProxied + ] = instances; + // STEP 5: Deploy the GeneralDelegateManagerFactory - - I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // STEP 6: Deploy the GeneralDelegateManagerFactory - - P_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); - - assert.notEqual( - P_GeneralPermissionManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralDelegateManagerFactory contract was not deployed" - ); - + [P_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); // STEP 7: Deploy the DummySTOFactory - - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" - ); - - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 8: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the Paid GeneralDelegateManagerFactory - await I_MRProxied.registerModule(P_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); + [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} + PolymathRegistry: ${I_PolymathRegistry.address} + SecurityTokenRegistryProxy: ${I_SecurityTokenRegistryProxy.address} + SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} + ModuleRegistryProxy ${I_ModuleRegistryProxy.address} + ModuleRegistry: ${I_ModuleRegistry.address} + FeatureRegistry: ${I_FeatureRegistry.address} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + STFactory: ${I_STFactory.address} + GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); }); - describe("Generate the SecurityToken", async() => { - + describe("Generate the SecurityToken", async () => { it("Should register the ticker before the generation of the security token", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from: token_owner }); assert.equal(tx.logs[0].args._owner, token_owner); assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); }); @@ -258,50 +151,47 @@ contract('GeneralPermissionManager', accounts => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); + let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner }); // Verify the successful generation of the security token assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); + const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({ from: _blockNo }), 1); // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toAscii(log.args._name).replace(/\u0000/g, ""), "GeneralTransferManager"); }); it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); + let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; + I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); it("Should successfully attach the General permission manager factory with the security token", async () => { - let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because Token is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); + await catchRevert( + I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { + from: token_owner + }) + ); }); it("Should successfully attach the General permission manager factory with the security token", async () => { let snapId = await takeSnapshot(); - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); + await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), { from: token_owner }); + const tx = await I_SecurityToken.addModule( + P_GeneralPermissionManagerFactory.address, + "0x", + web3.utils.toWei("500", "ether"), + 0, + { from: token_owner } + ); assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), "GeneralPermissionManager", "GeneralPermissionManagerFactory module was not added" ); @@ -313,8 +203,7 @@ contract('GeneralPermissionManager', accounts => { const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), "GeneralPermissionManager", "GeneralPermissionManagerFactory module was not added" ); @@ -323,47 +212,34 @@ contract('GeneralPermissionManager', accounts => { }); - describe("General Permission Manager test cases", async() => { - - it("Get the init data", async() => { + describe("General Permission Manager test cases", async () => { + it("Get the init data", async () => { let tx = await I_GeneralPermissionManager.getInitFunction.call(); - assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ""), 0); }); - it("Should fail in adding the delegate -- msg.sender doesn't have permission", async() => { - let errorThrown = false; - try { - let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}); - } catch(error) { - console.log(` tx revert -> msg.sender doesn't have permission`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async () => { + await catchRevert(I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1 })); }); - it("Should fail in adding the delegate -- no delegate details provided", async() => { - let errorThrown = false; - try { - let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: account_investor1}); - } catch(error) { - console.log(` tx revert -> delegate details were not provided`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + it("Should fail to provide the permission-- because delegate is not yet added", async () => { + await catchRevert( + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { + from: token_owner + }) + ); + }); + + it("Should fail in adding the delegate -- msg.sender doesn't have permission", async() => { + await catchRevert( + I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}) + ); }); - it("Should fail to provide the permission -- because delegate is not yet added", async() => { - let errorThrown = false; - try { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); - } catch(error) { - console.log(` tx revert -> Delegate is not yet added`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + it("Should fail in adding the delegate -- no delegate details provided", async() => { + await catchRevert( + I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: account_investor1}) + ); }); it("Should successfuly add the delegate", async() => { @@ -371,29 +247,35 @@ contract('GeneralPermissionManager', accounts => { assert.equal(tx.logs[0].args._delegate, account_delegate); }); - it("Should fail to provide the permission", async() => { - let errorThrown = false; - try { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1}); - } catch(error) { - console.log(` tx revert -> msg.sender doesn't have permission`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + it("Should fail to provide the permission", async () => { + await catchRevert( + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { + from: account_investor1 + }) + ); }); - it("Should check the permission", async() => { - assert.isFalse(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); + it("Should check the permission", async () => { + assert.isFalse( + await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST") + ); }); - it("Should provide the permission", async() => { - let tx = await I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); + it("Should provide the permission", async () => { + let tx = await I_GeneralPermissionManager.changePermission( + account_delegate, + I_GeneralTransferManager.address, + "WHITELIST", + true, + { from: token_owner } + ); assert.equal(tx.logs[0].args._delegate, account_delegate); }); - it("Should check the permission", async() => { - assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST")); + it("Should check the permission", async () => { + assert.isTrue( + await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST") + ); }); it("Should check the delegate details", async() => { @@ -403,12 +285,9 @@ contract('GeneralPermissionManager', accounts => { "Wrong delegate address get checked"); }); - it("Should get the permission of the general permission manager contract", async() => { + it("Should get the permission of the general permission manager contract", async () => { let tx = await I_GeneralPermissionManager.getPermissions.call(); - assert.equal(web3.utils.toAscii(tx[0]) - .replace(/\u0000/g, ''), - "CHANGE_PERMISSION", - "Wrong permissions"); + assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ""), "CHANGE_PERMISSION", "Wrong permissions"); }); it("Should return all delegates", async() => { @@ -464,30 +343,32 @@ contract('GeneralPermissionManager', accounts => { }); - describe("General Permission Manager Factory test cases", async() => { - it("should get the exact details of the factory", async() => { - assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(),0); - assert.equal((await I_GeneralPermissionManagerFactory.getTypes.call())[0],1); - assert.equal(web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "GeneralPermissionManager", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getDescription.call(), - "Manage permissions within the Security Token and attached modules", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), - "General Permission Manager", - "Wrong Module added"); - assert.equal(await I_GeneralPermissionManagerFactory.getInstructions.call(), - "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", - "Wrong Module added"); - + describe("General Permission Manager Factory test cases", async () => { + it("should get the exact details of the factory", async () => { + assert.equal(await I_GeneralPermissionManagerFactory.setupCost.call(), 0); + assert.equal((await I_GeneralPermissionManagerFactory.getTypes.call())[0], 1); + assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), "1.0.0"); + assert.equal( + web3.utils.toAscii(await I_GeneralPermissionManagerFactory.getName.call()).replace(/\u0000/g, ""), + "GeneralPermissionManager", + "Wrong Module added" + ); + assert.equal( + await I_GeneralPermissionManagerFactory.getDescription.call(), + "Manage permissions within the Security Token and attached modules", + "Wrong Module added" + ); + assert.equal(await I_GeneralPermissionManagerFactory.getTitle.call(), "General Permission Manager", "Wrong Module added"); + assert.equal( + await I_GeneralPermissionManagerFactory.getInstructions.call(), + "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required.", + "Wrong Module added" + ); }); - it("Should get the tags of the factory", async() => { + it("Should get the tags of the factory", async () => { let tags = await I_GeneralPermissionManagerFactory.getTags.call(); - assert.equal(tags.length,0); + assert.equal(tags.length, 0); }); }); - }); diff --git a/test/x_weighted_vote_checkpoint.js b/test/x_weighted_vote_checkpoint.js deleted file mode 100644 index 6adbce5a0..000000000 --- a/test/x_weighted_vote_checkpoint.js +++ /dev/null @@ -1,536 +0,0 @@ -import latestTime from './helpers/latestTime'; -import {signData} from './helpers/signData'; -import { pk } from './helpers/testprivateKey'; -import { duration, ensureException, promisifyLogWatch, latestBlock } from './helpers/utils'; -import takeSnapshot, { increaseTime, revertToSnapshot } from './helpers/time'; -import { encodeProxyCall, encodeModuleCall } from './helpers/encodeCall'; - -const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') -const DummySTOFactory = artifacts.require('./DummySTOFactory.sol'); -const DummySTO = artifacts.require('./DummySTO.sol'); -const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); -const ModuleRegistryProxy = artifacts.require('./ModuleRegistryProxy.sol'); -const SecurityToken = artifacts.require('./SecurityToken.sol'); -const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); -const SecurityTokenRegistryProxy = artifacts.require('./SecurityTokenRegistryProxy.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'); -const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); -const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const PolyTokenFaucet = artifacts.require('./PolyTokenFaucet.sol'); - -const WeightedVoteCheckpointFactory = artifacts.require('./WeightedVoteCheckpointFactory.sol'); -const WeightedVoteCheckpoint = artifacts.require('./WeightedVoteCheckpoint'); - -const Web3 = require('web3'); -const BigNumber = require('bignumber.js'); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port - -contract('WeightedVoteCheckpoint', accounts => { - - // Accounts Variable declaration - let account_polymath; - let account_issuer; - let token_owner; - let token_owner_pk; - let account_investor1; - let account_investor2; - let account_investor3; - let account_investor4; - let account_temp; - // investor Details - let fromTime = latestTime(); - let toTime = latestTime(); - let expiryTime = toTime + duration.days(15); - - let message = "Transaction Should Fail!"; - - // Contract Instance Declaration - let I_SecurityTokenRegistryProxy; - let I_GeneralTransferManagerFactory; - let I_GeneralPermissionManager; - let I_GeneralTransferManager; - let I_ModuleRegistryProxy; - let I_ModuleRegistry; - let I_FeatureRegistry; - let I_SecurityTokenRegistry; - let I_DummySTOFactory; - let I_STFactory; - let I_SecurityToken; - let I_MRProxied; - let I_STRProxied; - let I_DummySTO; - let I_PolyToken; - let I_PolymathRegistry; - let I_WeightedVoteCheckpointFactory; - let P_WeightedVoteCheckpointFactory; - let I_WeightedVoteCheckpoint; - let P_WeightedVoteCheckpoint; - - // SecurityToken Details - const name = "Team"; - const symbol = "sap"; - const tokenDetails = "This is equity type of issuance"; - const decimals = 18; - const contact = "team@polymath.network"; - const delegateDetails = "Hello I am legit delegate"; - - // Module key - const delegateManagerKey = 1; - const transferManagerKey = 2; - const stoKey = 3; - const checkpointKey = 4; - - // Initial fee for ticker registry and security token registry - const initRegFee = web3.utils.toWei("250"); - - // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei('10', 'ether'); - const someString = "A string which is not used"; - const STOParameters = ['uint256', 'uint256', 'uint256', 'string']; - const STRProxyParameters = ['address', 'address', 'uint256', 'uint256', 'address', 'address']; - const MRProxyParameters = ['address', 'address']; - - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); - - before(async() => { - // Accounts setup - account_polymath = accounts[0]; - account_issuer = accounts[1]; - - token_owner = account_issuer; - token_owner_pk = pk.account_1; - - account_investor1 = accounts[6]; - account_investor2 = accounts[7]; - account_investor3 = accounts[8]; - account_investor4 = accounts[9]; - account_temp = accounts[2]; - - - // ----------- POLYMATH NETWORK Configuration ------------ - - // Step 0: Deploy the PolymathRegistry - I_PolymathRegistry = await PolymathRegistry.new({from: account_polymath}); - - // Step 1: Deploy the token Faucet and Mint tokens for token_owner - I_PolyToken = await PolyTokenFaucet.new(); - await I_PolyToken.getTokens((10000 * Math.pow(10, 18)), token_owner); - - // Step 2: Deploy the FeatureRegistry - - I_FeatureRegistry = await FeatureRegistry.new( - I_PolymathRegistry.address, - { - from: account_polymath - }); - - // STEP 3: Deploy the ModuleRegistry - - I_ModuleRegistry = await ModuleRegistry.new({from:account_polymath}); - // Step 3 (b): Deploy the proxy and attach the implementation contract to it - I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from:account_polymath}); - let bytesMRProxy = encodeProxyCall(MRProxyParameters, [I_PolymathRegistry.address, account_polymath]); - await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesMRProxy, {from: account_polymath}); - I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); - - // STEP 4: Deploy the GeneralTransferManagerFactory - - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "GeneralTransferManagerFactory contract was not deployed" - ); - - // STEP 5: Deploy the WeightedVoteCheckpointFactory - - I_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - assert.notEqual( - I_WeightedVoteCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "WeightedVoteCheckpointFactory contract was not deployed" - ); - console.log("deployed weight vote factory to "+I_WeightedVoteCheckpointFactory.address); - - // STEP 6: Deploy the WeightedVoteCheckpointFactory with fees - - P_WeightedVoteCheckpointFactory = await WeightedVoteCheckpointFactory.new(I_PolyToken.address, web3.utils.toWei("500","ether"), 0, 0, {from:account_polymath}); - - assert.notEqual( - P_WeightedVoteCheckpointFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "WeightedVoteCheckpointFactory contract with fees was not deployed" - ); - - // STEP 7: Deploy the DummySTOFactory - - I_DummySTOFactory = await DummySTOFactory.new(I_PolyToken.address, 0, 0, 0, {from:account_polymath}); - - assert.notEqual( - I_DummySTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "DummySTOFactory contract was not deployed" - ); - - - // Step 8: Deploy the STFactory contract - - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, {from : account_polymath }); - - assert.notEqual( - I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "STFactory contract was not deployed", - ); - - // Step 9: Deploy the SecurityTokenRegistry contract - - I_SecurityTokenRegistry = await SecurityTokenRegistry.new({from: account_polymath }); - - assert.notEqual( - I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", - "SecurityTokenRegistry contract was not deployed", - ); - - // Step 10: Deploy the proxy and attach the implementation contract to it. - I_SecurityTokenRegistryProxy = await SecurityTokenRegistryProxy.new({from: account_polymath}); - let bytesProxy = encodeProxyCall(STRProxyParameters, [I_PolymathRegistry.address, I_STFactory.address, initRegFee, initRegFee, I_PolyToken.address, account_polymath]); - await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, {from: account_polymath}); - I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); - - // Step 11: update the registries addresses from the PolymathRegistry contract - await I_PolymathRegistry.changeAddress("PolyToken", I_PolyToken.address, {from: account_polymath}) - await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); - await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistryProxy.address, {from: account_polymath}); - await I_MRProxied.updateFromRegistry({from: account_polymath}); - - // STEP 8: Register the Modules with the ModuleRegistry contract - - // (A) : Register the GeneralTransferManagerFactory - await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); - - // (B) : Register the GeneralDelegateManagerFactory - await I_MRProxied.registerModule(I_WeightedVoteCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_WeightedVoteCheckpointFactory.address, true, { from: account_polymath }); - - // (B) : Register the Paid GeneralDelegateManagerFactory - await I_MRProxied.registerModule(P_WeightedVoteCheckpointFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(P_WeightedVoteCheckpointFactory.address, true, { from: account_polymath }); - - // (C) : Register the STOFactory - await I_MRProxied.registerModule(I_DummySTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_DummySTOFactory.address, true, { from: account_polymath }); - - // Printing all the contract addresses - console.log(` - --------------------- Polymath Network Smart Contracts: --------------------- - PolymathRegistry: ${PolymathRegistry.address} - SecurityTokenRegistryProxy: ${SecurityTokenRegistryProxy.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} - ModuleRegistryProxy ${ModuleRegistryProxy.address} - ModuleRegistry: ${ModuleRegistry.address} - FeatureRegistry: ${FeatureRegistry.address} - - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - - DummySTOFactory: ${I_DummySTOFactory.address} - ----------------------------------------------------------------------------- - `); - }); - - describe("Generate the SecurityToken", async() => { - - it("Should register the ticker before the generation of the security token", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let tx = await I_STRProxied.registerTicker(token_owner, symbol, contact, { from : token_owner }); - assert.equal(tx.logs[0].args._owner, token_owner); - assert.equal(tx.logs[0].args._ticker, symbol.toUpperCase()); - }); - - it("Should generate the new security token with the same symbol as registered above", async () => { - await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); - let _blockNo = latestBlock(); - let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner}); - - // Verify the successful generation of the security token - assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - - I_SecurityToken = SecurityToken.at(tx.logs[1].args._securityTokenAddress); - - const log = await promisifyLogWatch(I_SecurityToken.ModuleAdded({from: _blockNo}), 1); - - // Verify that GeneralTransferManager module get added successfully or not - assert.equal(log.args._types[0].toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); - }); - - it("Should intialize the auto attached modules", async () => { - let moduleData = (await I_SecurityToken.getModulesByType(2))[0]; - I_GeneralTransferManager = GeneralTransferManager.at(moduleData); - }); - - it("Should fail to attach the WeightedVoteCheckpoint module to the security token if fee not paid", async () => { - let errorThrown = false; - await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); - try { - const tx = await I_SecurityToken.addModule(P_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because setup fee is not paid`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully attach the WeightedVoteCheckpoint module to the security token after fees been paid", async () => { - await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("500", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_WeightedVoteCheckpointFactory.address, "", web3.utils.toWei("500", "ether"), 0, { from: token_owner }); - console.log("weightVoteFactory PAID Address is " + P_WeightedVoteCheckpointFactory.address); - console.log(tx.logs); - assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); - assert.equal(web3.utils.hexToUtf8(tx.logs[3].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); - P_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[3].args._module); - }); - - it("Should successfully attach the Weighted Vote Checkpoint factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_WeightedVoteCheckpointFactory.address, "0x", 0, 0, { from: token_owner }); - console.log("weightVoteFactory Address is " + I_WeightedVoteCheckpointFactory.address); - console.log(tx.logs); - assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "WeightedVoteCheckpoint doesn't get deployed"); - assert.equal(web3.utils.hexToUtf8(tx.logs[2].args._name),"WeightedVoteCheckpoint","WeightedVoteCheckpoint module was not added"); - I_WeightedVoteCheckpoint = WeightedVoteCheckpoint.at(tx.logs[2].args._module); - }); - }); - - describe("Preparation", async() => { - it("Should successfully mint tokens for first investor account", async() => { - await I_GeneralTransferManager.modifyWhitelist( - account_investor1, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - await I_SecurityToken.mint(account_investor1, web3.utils.toWei('1', 'ether'), { from: token_owner }); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - }); - - it("Should successfully mint tokens for second investor account", async() => { - await I_GeneralTransferManager.modifyWhitelist( - account_investor2, - latestTime(), - latestTime(), - latestTime() + duration.days(30), - true, - { - from: account_issuer, - gas: 500000 - }); - await I_SecurityToken.mint(account_investor2, web3.utils.toWei('2', 'ether'), { from: token_owner }); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - }); - }); - - describe("Create ballot", async() => { - - it("Should fail to create a new ballot if not owner", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: account_temp }); - } catch(error) { - console.log(` tx -> failed because msg.sender is not owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully create a new ballot", async() => { - let tx = await I_WeightedVoteCheckpoint.createBallot(duration.hours(2), { from: token_owner }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); - }); - }); - - describe("Create custom ballot", async() => { - - it("Should fail to create a new custom ballot with endTime before startTime", async() => { - let errorThrown = false; - try { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(5); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because endTime before startTime`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to create a new custom ballot if checkpointId does not exist", async() => { - let errorThrown = false; - try { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(15); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 10, { from: token_owner }); - } catch(error) { - console.log(` tx -> failed because checkpointId does not exist`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to create a new custom ballot if not owner", async() => { - let errorThrown = false; - try { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(15); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: account_temp }); - } catch(error) { - console.log(` tx -> failed because msg.sender is not owner`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully create a new custom ballot", async() => { - let startTime = latestTime() + duration.minutes(10); - let endTime = latestTime() + duration.minutes(15); - let tx = await I_WeightedVoteCheckpoint.createCustomBallot(startTime,endTime, 1, { from: token_owner }); - assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "New ballot should be created at checkpoint 1"); - }); - }); - - describe("Cast vote", async() => { - - it("Should fail to cast a vote if token balance is zero", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor3 }); - } catch(error) { - console.log(` tx -> failed because token balance is zero`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to cast a vote if voting period has not started", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); - } catch(error) { - console.log(` tx -> failed because voting period has not started`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should fail to cast a vote if voting period has ended", async() => { - await increaseTime(duration.minutes(20)); - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(true,1, { from: account_investor1 }); - } catch(error) { - console.log(` tx -> failed because voting period has ended`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - it("Should successfully cast a vote from first investor", async() => { - let tx = await I_WeightedVoteCheckpoint.castVote(false, 0, { from: account_investor1 }); - - console.log(tx.logs); - - assert.equal(tx.logs[0].args._investor, account_investor1, "Failed to record vote"); - assert.equal(tx.logs[0].args._vote, false, "Failed to record vote"); - assert.equal(tx.logs[0].args._weight, web3.utils.toWei('1', 'ether'), "Failed to record vote"); - assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); - assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); - }); - - it("Should successfully cast a vote from second investor", async() => { - let tx = await I_WeightedVoteCheckpoint.castVote(true, 0, { from: account_investor2 }); - - assert.equal(tx.logs[0].args._investor, account_investor2, "Failed to record vote"); - assert.equal(tx.logs[0].args._vote, true, "Failed to record vote"); - assert.equal(tx.logs[0].args._weight, web3.utils.toWei('2', 'ether'), "Failed to record vote"); - assert.equal(tx.logs[0].args._ballotId, 0, "Failed to record vote"); - assert.equal(tx.logs[0].args._time, latestTime(), "Failed to record vote"); - }); - - it("Should fail to cast a vote again", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(false,0, { from: account_investor1 }); - } catch(error) { - console.log(` tx -> failed because holder already voted`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - }); - - describe("Get results", async() => { - - it("Should successfully get the results", async() => { - let tx = await I_WeightedVoteCheckpoint.getResults(0, { from: token_owner }); - assert.equal(tx[0], web3.utils.toWei('2', 'ether'), "Failed to get results"); - assert.equal(tx[1], web3.utils.toWei('1', 'ether'), "Failed to get results"); - assert.equal(tx[2], 0, "Failed to get results"); - }); - }); - - describe("Active/Deactive Ballot", async() => { - - it("Should successfully deactive the ballot", async() => { - let tx = await I_WeightedVoteCheckpoint.setActiveStatsBallot(0, false, { from: token_owner }); - let tx2 = await I_WeightedVoteCheckpoint.ballots(0, { from: token_owner }); - assert.equal(tx2[7], false); - }); - - it("Should fail to cast a vote if ballot is deactivated", async() => { - let errorThrown = false; - try { - let tx = await I_WeightedVoteCheckpoint.castVote(true,0, { from: account_investor1 }); - } catch(error) { - console.log(` tx -> failed because ballot is deactivated`.grey); - ensureException(error); - errorThrown = true; - } - assert.ok(errorThrown, message); - }); - - - it("Should successfully active the same ballot again", async() => { - let tx = await I_WeightedVoteCheckpoint.setActiveStatsBallot(0, true, { from: token_owner }); - let tx2 = await I_WeightedVoteCheckpoint.ballots(0, { from: token_owner }); - assert.equal(tx2[7], true); - }); - }); - -}); From acb36c5f8d442f5af278917e47d7f55d20c301bf Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 12 Oct 2018 11:20:35 +0530 Subject: [PATCH 130/142] Delete LockupVolumeRestrictionTransferManager.sol --- ...LockupVolumeRestrictionTransferManager.sol | 374 ------------------ 1 file changed, 374 deletions(-) delete mode 100644 contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol diff --git a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol deleted file mode 100644 index 59a8b53b0..000000000 --- a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManager.sol +++ /dev/null @@ -1,374 +0,0 @@ -pragma solidity ^0.4.24; - -import "./ITransferManager.sol"; -import "openzeppelin-solidity/contracts/math/SafeMath.sol"; - - -contract LockupVolumeRestrictionTransferManager is ITransferManager { - - using SafeMath for uint256; - - // permission definition - bytes32 public constant ADMIN = "ADMIN"; - - // a per-user lockup - struct LockUp { - uint lockUpPeriodSeconds; // total period of lockup (seconds) - uint releaseFrequencySeconds; // how often to release a tranche of tokens (seconds) - uint startTime; // when this lockup starts (seconds) - uint totalAmount; // total amount of locked up tokens - uint alreadyWithdrawn; // amount already withdrawn for this lockup - } - - // maps user addresses to an array of lockups for that user - mapping (address => LockUp[]) internal lockUps; - - event AddNewLockUp( - address indexed userAddress, - uint lockUpPeriodSeconds, - uint releaseFrequencySeconds, - uint startTime, - uint totalAmount, - uint indexed addedIndex - ); - - event RemoveLockUp( - address indexed userAddress, - uint lockUpPeriodSeconds, - uint releaseFrequencySeconds, - uint startTime, - uint totalAmount, - uint indexed removedIndex - ); - - event ModifyLockUp( - address indexed userAddress, - uint lockUpPeriodSeconds, - uint releaseFrequencySeconds, - uint startTime, - uint totalAmount, - uint indexed modifiedIndex - ); - - /** - * @notice Constructor - * @param _securityToken Address of the security token - * @param _polyAddress Address of the polytoken - */ - constructor (address _securityToken, address _polyAddress) - public - Module(_securityToken, _polyAddress) - { - } - - - /** @notice Used to verify the transfer transaction and prevent locked up tokens from being transferred - * @param _from Address of the sender - * @param _amount The amount of tokens to transfer - * @param _isTransfer Whether or not this is an actual transfer or just a test to see if the tokens would be transferrable - */ - function verifyTransfer(address _from, address /* _to*/, uint256 _amount, bytes /* _data */, bool _isTransfer) public returns(Result) { - // only attempt to verify the transfer if the token is unpaused, this isn't a mint txn, and there exists a lockup for this user - if (!paused && _from != address(0) && lockUps[_from].length != 0) { - // check if this transfer is valid - return _checkIfValidTransfer(_from, _amount, _isTransfer); - } - return Result.NA; - } - - /** - * @notice Lets the admin create a volume restriction lockup for a given address. - * @param userAddress Address of the user whose tokens should be locked up - * @param lockUpPeriodSeconds Total period of lockup (seconds) - * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) - * @param startTime When this lockup starts (seconds) - * @param totalAmount Total amount of locked up tokens - */ - function addLockUp(address userAddress, uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount) public withPerm(ADMIN) { - - _checkLockUpParams(lockUpPeriodSeconds, releaseFrequencySeconds, totalAmount); - - // if a startTime of 0 is passed in, then start now. - if (startTime == 0) { - startTime = now; - } - - lockUps[userAddress].push(LockUp(lockUpPeriodSeconds, releaseFrequencySeconds, startTime, totalAmount, 0)); - - emit AddNewLockUp( - userAddress, - lockUpPeriodSeconds, - releaseFrequencySeconds, - startTime, - totalAmount, - lockUps[userAddress].length - 1 - ); - } - - /** - * @notice Lets the admin create multiple volume restriction lockups for multiple given addresses. - * @param userAddresses Array of address of the user whose tokens should be locked up - * @param lockUpPeriodsSeconds Array of total periods of lockup (seconds) - * @param releaseFrequenciesSeconds Array of how often to release a tranche of tokens (seconds) - * @param startTimes Array of When this lockup starts (seconds) - * @param totalAmounts Array of total amount of locked up tokens - */ - function addLockUpMulti(address[] userAddresses, uint[] lockUpPeriodsSeconds, uint[] releaseFrequenciesSeconds, uint[] startTimes, uint[] totalAmounts) external withPerm(ADMIN) { - - // make sure input params are sane - require( - userAddresses.length == lockUpPeriodsSeconds.length && - userAddresses.length == releaseFrequenciesSeconds.length && - userAddresses.length == startTimes.length && - userAddresses.length == totalAmounts.length, - "Input array length mis-match" - ); - - for (uint i = 0; i < userAddresses.length; i++) { - addLockUp(userAddresses[i], lockUpPeriodsSeconds[i], releaseFrequenciesSeconds[i], startTimes[i], totalAmounts[i]); - } - - } - - /** - * @notice Lets the admin remove a user's lock up - * @param userAddress Address of the user whose tokens are locked up - * @param lockUpIndex The index of the LockUp to remove for the given userAddress - */ - function removeLockUp(address userAddress, uint lockUpIndex) public withPerm(ADMIN) { - LockUp[] storage userLockUps = lockUps[userAddress]; - require(lockUpIndex < userLockUps.length, "Array out of bounds exception"); - - LockUp memory toRemove = userLockUps[lockUpIndex]; - - emit RemoveLockUp( - userAddress, - toRemove.lockUpPeriodSeconds, - toRemove.releaseFrequencySeconds, - toRemove.startTime, - toRemove.totalAmount, - lockUpIndex - ); - - if (lockUpIndex < userLockUps.length - 1) { - // move the last element in the array into the index that is desired to be removed. - userLockUps[lockUpIndex] = userLockUps[userLockUps.length - 1]; - } - // delete the last element - userLockUps.length--; - } - - /** - * @notice Lets the admin modify a volume restriction lockup for a given address. - * @param userAddress Address of the user whose tokens should be locked up - * @param lockUpIndex The index of the LockUp to edit for the given userAddress - * @param lockUpPeriodSeconds Total period of lockup (seconds) - * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) - * @param startTime When this lockup starts (seconds) - * @param totalAmount Total amount of locked up tokens - */ - function modifyLockUp(address userAddress, uint lockUpIndex, uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount) public withPerm(ADMIN) { - require(lockUpIndex < lockUps[userAddress].length, "Array out of bounds exception"); - - // if a startTime of 0 is passed in, then start now. - if (startTime == 0) { - startTime = now; - } - - _checkLockUpParams(lockUpPeriodSeconds, releaseFrequencySeconds, totalAmount); - - // Get the lockup from the master list and edit it - lockUps[userAddress][lockUpIndex] = LockUp( - lockUpPeriodSeconds, - releaseFrequencySeconds, - startTime, - totalAmount, - lockUps[userAddress][lockUpIndex].alreadyWithdrawn - ); - - emit ModifyLockUp( - userAddress, - lockUpPeriodSeconds, - releaseFrequencySeconds, - startTime, - totalAmount, - lockUpIndex - ); - } - - /** - * @notice Get the length of the lockups array for a specific user address - * @param userAddress Address of the user whose tokens should be locked up - */ - function getLockUpsLength(address userAddress) public view returns (uint) { - return lockUps[userAddress].length; - } - - /** - * @notice Get a specific element in a user's lockups array given the user's address and the element index - * @param userAddress Address of the user whose tokens should be locked up - * @param lockUpIndex The index of the LockUp to edit for the given userAddress - */ - function getLockUp(address userAddress, uint lockUpIndex) public view returns (uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount, uint alreadyWithdrawn) { - require(lockUpIndex < lockUps[userAddress].length, "Array out of bounds exception"); - LockUp storage userLockUp = lockUps[userAddress][lockUpIndex]; - return ( - userLockUp.lockUpPeriodSeconds, - userLockUp.releaseFrequencySeconds, - userLockUp.startTime, - userLockUp.totalAmount, - userLockUp.alreadyWithdrawn - ); - } - - /** - * @notice This function returns the signature of configure function - */ - function getInitFunction() public pure returns (bytes4) { - return bytes4(0); - } - - /** - * @notice Return the permissions flag that are associated with Percentage transfer Manager - */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); - allPermissions[0] = ADMIN; - return allPermissions; - } - - /** - * @notice Takes a userAddress as input, and returns a uint that represents the number of tokens allowed to be withdrawn right now - * @param userAddress Address of the user whose lock ups should be checked - */ - function _checkIfValidTransfer(address userAddress, uint amount, bool isTransfer) internal returns (Result) { - // get lock up array for this user - LockUp[] storage userLockUps = lockUps[userAddress]; - - // maps the index of userLockUps to the amount allowed in this transfer - uint[] memory allowedAmountPerLockup = new uint[](userLockUps.length); - - uint[3] memory tokenSums = [ - uint256(0), // allowed amount right now - uint256(0), // total locked up, ever - uint256(0) // already withdrawn, ever - ]; - - // loop over the user's lock ups - for (uint i = 0; i < userLockUps.length; i++) { - LockUp storage aLockUp = userLockUps[i]; - - uint allowedAmountForThisLockup = 0; - - // check if lockup has entirely passed - if (now >= aLockUp.startTime.add(aLockUp.lockUpPeriodSeconds)) { - // lockup has passed, or not started yet. allow all. - allowedAmountForThisLockup = aLockUp.totalAmount.sub(aLockUp.alreadyWithdrawn); - } else if (now >= aLockUp.startTime) { - // lockup is active. calculate how many to allow to be withdrawn right now - // calculate how many periods have elapsed already - uint elapsedPeriods = (now.sub(aLockUp.startTime)).div(aLockUp.releaseFrequencySeconds); - // calculate the total number of periods, overall - uint totalPeriods = aLockUp.lockUpPeriodSeconds.div(aLockUp.releaseFrequencySeconds); - // calculate how much should be released per period - uint amountPerPeriod = aLockUp.totalAmount.div(totalPeriods); - // calculate the number of tokens that should be released, - // multiplied by the number of periods that have elapsed already - // and add it to the total tokenSums[0] - allowedAmountForThisLockup = amountPerPeriod.mul(elapsedPeriods).sub(aLockUp.alreadyWithdrawn); - - } - // tokenSums[0] is allowed sum - tokenSums[0] = tokenSums[0].add(allowedAmountForThisLockup); - // tokenSums[1] is total locked up - tokenSums[1] = tokenSums[1].add(aLockUp.totalAmount); - // tokenSums[2] is total already withdrawn - tokenSums[2] = tokenSums[2].add(aLockUp.alreadyWithdrawn); - - allowedAmountPerLockup[i] = allowedAmountForThisLockup; - } - - // tokenSums[0] is allowed sum - if (amount <= tokenSums[0]) { - // transfer is valid and will succeed. - if (!isTransfer) { - // if this isn't a real transfer, don't subtract the withdrawn amounts from the lockups. it's a "read only" txn - return Result.VALID; - } - - // we are going to write the withdrawn balances back to the lockups, so make sure that the person calling this function is the securityToken itself, since its public - require(msg.sender == securityToken, "Sender is not securityToken"); - - // subtract amounts so they are now known to be withdrawen - for (i = 0; i < userLockUps.length; i++) { - aLockUp = userLockUps[i]; - - // tokenSums[0] is allowed sum - if (allowedAmountPerLockup[i] >= tokenSums[0]) { - aLockUp.alreadyWithdrawn = aLockUp.alreadyWithdrawn.add(tokenSums[0]); - // we withdrew the entire tokenSums[0] from the lockup. We are done. - break; - } else { - // we have to split the tokenSums[0] across mutiple lockUps - aLockUp.alreadyWithdrawn = aLockUp.alreadyWithdrawn.add(allowedAmountPerLockup[i]); - // subtract the amount withdrawn from this lockup - tokenSums[0] = tokenSums[0].sub(allowedAmountPerLockup[i]); - } - - } - return Result.VALID; - } - - return _checkIfUnlockedTokenTransferIsPossible(userAddress, amount, tokenSums[1], tokenSums[2]); - } - - function _checkIfUnlockedTokenTransferIsPossible(address userAddress, uint amount, uint totalSum, uint alreadyWithdrawnSum) internal view returns (Result) { - // the amount the user wants to withdraw is greater than their allowed amounts according to the lockups. however, if the user has like, 10 tokens, but only 4 are locked up, we should let the transfer go through for those 6 that aren't locked up - uint currentUserBalance = ISecurityToken(securityToken).balanceOf(userAddress); - uint stillLockedAmount = totalSum.sub(alreadyWithdrawnSum); - if (currentUserBalance >= stillLockedAmount && amount <= currentUserBalance.sub(stillLockedAmount)) { - // the user has more tokens in their balance than are actually locked up. they should be allowed to withdraw the difference - return Result.VALID; - } - return Result.INVALID; - } - - - /** - * @notice Parameter checking function for creating or editing a lockup. This function will cause an exception if any of the parameters are bad. - * @param lockUpPeriodSeconds Total period of lockup (seconds) - * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) - * @param totalAmount Total amount of locked up tokens - */ - function _checkLockUpParams(uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint totalAmount) internal view { - require(lockUpPeriodSeconds != 0, "lockUpPeriodSeconds cannot be zero"); - require(releaseFrequencySeconds != 0, "releaseFrequencySeconds cannot be zero"); - require(totalAmount != 0, "totalAmount cannot be zero"); - - // check that the total amount to be released isn't too granular - require( - totalAmount % ISecurityToken(securityToken).granularity() == 0, - "The total amount to be released is more granular than allowed by the token" - ); - - // check that releaseFrequencySeconds evenly divides lockUpPeriodSeconds - require( - lockUpPeriodSeconds % releaseFrequencySeconds == 0, - "lockUpPeriodSeconds must be evenly divisible by releaseFrequencySeconds" - ); - - // check that totalPeriods evenly divides totalAmount - uint totalPeriods = lockUpPeriodSeconds.div(releaseFrequencySeconds); - require( - totalAmount % totalPeriods == 0, - "The total amount being locked up must be evenly divisible by the number of total periods" - ); - - // make sure the amount to be released per period is not too granular for the token - uint amountPerPeriod = totalAmount.div(totalPeriods); - require( - amountPerPeriod % ISecurityToken(securityToken).granularity() == 0, - "The amount to be released per period is more granular than allowed by the token" - ); - } -} From 1bde6b3af8de4ef8e942da77b15b15195a64fc2c Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 12 Oct 2018 11:20:45 +0530 Subject: [PATCH 131/142] Delete LockupVolumeRestrictionTransferManagerFactory.sol --- ...olumeRestrictionTransferManagerFactory.sol | 104 ------------------ 1 file changed, 104 deletions(-) delete mode 100644 contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol diff --git a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol deleted file mode 100644 index 0bb34fce2..000000000 --- a/contracts/modules/TransferManager/LockupVolumeRestrictionTransferManagerFactory.sol +++ /dev/null @@ -1,104 +0,0 @@ -pragma solidity ^0.4.24; - -import "./LockupVolumeRestrictionTransferManager.sol"; -import "../ModuleFactory.sol"; - -/** - * @title Factory for deploying ManualApprovalTransferManager module - */ -contract LockupVolumeRestrictionTransferManagerFactory is ModuleFactory { - - /** - * @notice Constructor - * @param _polyAddress Address of the polytoken - * @param _setupCost Setup cost of the module - * @param _usageCost Usage cost of the module - * @param _subscriptionCost Subscription cost of the module - */ - constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public - ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) - { - version = "1.0.0"; - name = "VolumeRestrictionTransferManager"; - title = "Lockup Volume Restriction Transfer Manager"; - description = "Manage transfers using lock ups over time"; - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - } - - /** - * @notice used to launch the Module with the help of factory - * @return address Contract address of the Module - */ - function deploy(bytes /* _data */) external returns(address) { - if (setupCost > 0) - require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); - address lockupVolumeRestrictionTransferManager = new LockupVolumeRestrictionTransferManager(msg.sender, address(polyToken)); - emit GenerateModuleFromFactory(address(lockupVolumeRestrictionTransferManager), getName(), address(this), msg.sender, now); - return address(lockupVolumeRestrictionTransferManager); - } - - /** - * @notice Type of the Module factory - * @return uint8 - */ - function getTypes() external view returns(uint8[]) { - uint8[] memory res = new uint8[](1); - res[0] = 2; - return res; - } - - /** - * @notice Get the name of the Module - */ - function getName() public view returns(bytes32) { - return name; - } - - /** - * @notice Get the description of the Module - */ - function getDescription() external view returns(string) { - return description; - } - - /** - * @notice Get the title of the Module - */ - function getTitle() external view returns(string) { - return title; - } - - /** - * @notice Get the version of the Module - */ - function getVersion() external view returns(string) { - return version; - } - - /** - * @notice Get the setup cost of the module - */ - function getSetupCost() external view returns (uint256) { - return setupCost; - } - - /** - * @notice Get the Instructions that helped to used the module - */ - function getInstructions() external view returns(string) { - return "Allows an issuer to set lockup periods for user addresses, with funds distributed over time. Init function takes no parameters."; - } - - /** - * @notice Get the tags related to the module factory - */ - function getTags() external view returns(bytes32[]) { - bytes32[] memory availableTags = new bytes32[](2); - availableTags[0] = "Volume"; - availableTags[1] = "Transfer Restriction"; - return availableTags; - } - - -} From 84c007762632dab0f7e29ef98023edcfcd342fee Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Fri, 12 Oct 2018 09:27:51 -0300 Subject: [PATCH 132/142] Cli permissions manager (#335) * Permission_manager command added * newDelegate fix * Issuer account is read from ./privKeyLocal * CLI Permission Manager update --- CLI/commands/ST20Generator.js | 3 +- CLI/commands/dividends_manager.js | 3 +- CLI/commands/helpers/contract_abis.js | 12 +- CLI/commands/permission_manager.js | 222 ++++++++++++++++++++++++++ CLI/polymath-cli.js | 9 ++ README.md | 2 +- 6 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 CLI/commands/permission_manager.js diff --git a/CLI/commands/ST20Generator.js b/CLI/commands/ST20Generator.js index 24ccdcbbb..530da89bb 100644 --- a/CLI/commands/ST20Generator.js +++ b/CLI/commands/ST20Generator.js @@ -20,7 +20,8 @@ const MODULES_TYPES = { PERMISSION: 1, TRANSFER: 2, STO: 3, - DIVIDENDS: 4 + DIVIDENDS: 4, + BURN: 5 } const cappedSTOFee = 20000; diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index c4f158cd6..fc9caab4e 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -18,7 +18,8 @@ const MODULES_TYPES = { PERMISSION: 1, TRANSFER: 2, STO: 3, - DIVIDENDS: 4 + DIVIDENDS: 4, + BURN: 5 } // App flow diff --git a/CLI/commands/helpers/contract_abis.js b/CLI/commands/helpers/contract_abis.js index a505579d2..b6c58cc38 100644 --- a/CLI/commands/helpers/contract_abis.js +++ b/CLI/commands/helpers/contract_abis.js @@ -7,11 +7,13 @@ let stoInterfaceABI; let cappedSTOABI; let usdTieredSTOABI; let generalTransferManagerABI; +let generalPermissionManagerABI; let polyTokenABI; let cappedSTOFactoryABI; let usdTieredSTOFactoryABI; let erc20DividendCheckpointABI; let etherDividendCheckpointABI; +let moduleInterfaceABI; let ownableABI; let moduleFactoryABI; @@ -25,16 +27,18 @@ try { cappedSTOABI = JSON.parse(require('fs').readFileSync('./build/contracts/CappedSTO.json').toString()).abi; usdTieredSTOABI = JSON.parse(require('fs').readFileSync('./build/contracts/USDTieredSTO.json').toString()).abi; generalTransferManagerABI = JSON.parse(require('fs').readFileSync('./build/contracts/GeneralTransferManager.json').toString()).abi; + generalPermissionManagerABI = JSON.parse(require('fs').readFileSync('./build/contracts/GeneralPermissionManager.json').toString()).abi; polyTokenABI = JSON.parse(require('fs').readFileSync('./build/contracts/PolyTokenFaucet.json').toString()).abi; cappedSTOFactoryABI = JSON.parse(require('fs').readFileSync('./build/contracts/CappedSTOFactory.json').toString()).abi; usdTieredSTOFactoryABI = JSON.parse(require('fs').readFileSync('./build/contracts/USDTieredSTOFactory.json').toString()).abi; erc20DividendCheckpointABI = JSON.parse(require('fs').readFileSync('./build/contracts/ERC20DividendCheckpoint.json').toString()).abi; etherDividendCheckpointABI = JSON.parse(require('fs').readFileSync('./build/contracts/EtherDividendCheckpoint.json').toString()).abi; + moduleInterfaceABI = JSON.parse(require('fs').readFileSync('./build/contracts/IModule.json').toString()).abi; ownableABI = JSON.parse(require('fs').readFileSync('./build/contracts/Ownable.json').toString()).abi; moduleFactoryABI = JSON.parse(require('fs').readFileSync('./build/contracts/ModuleFactory.json').toString()).abi; } catch (err) { console.log('\x1b[31m%s\x1b[0m',"Couldn't find contracts' artifacts. Make sure you ran truffle compile first"); - return; + throw err; } module.exports = { @@ -65,6 +69,9 @@ module.exports = { generalTransferManager: function () { return generalTransferManagerABI; }, + generalPermissionManager: function () { + return generalPermissionManagerABI; + }, polyToken: function () { return polyTokenABI; }, @@ -80,6 +87,9 @@ module.exports = { etherDividendCheckpoint: function () { return etherDividendCheckpointABI; }, + moduleInterface: function () { + return moduleInterfaceABI; + }, ownable: function () { return ownableABI; }, diff --git a/CLI/commands/permission_manager.js b/CLI/commands/permission_manager.js new file mode 100644 index 000000000..49a20f7e3 --- /dev/null +++ b/CLI/commands/permission_manager.js @@ -0,0 +1,222 @@ +var readlineSync = require('readline-sync'); +var chalk = require('chalk'); +var common = require('./common/common_functions'); +var global = require('./common/global'); +var contracts = require('./helpers/contract_addresses'); +var abis = require('./helpers/contract_abis'); + +// App flow +let tokenSymbol; +let securityTokenRegistry; +let securityToken; +let generalPermissionManager; + +const MODULES_TYPES = { + PERMISSION: 1, + TRANSFER: 2, + STO: 3, + DIVIDEND: 4, + BURN: 5 +} + +async function executeApp(remoteNetwork) { + await global.initialize(remoteNetwork); + + common.logAsciiBull(); + console.log("***********************************************"); + console.log("Welcome to the Command-Line Permission Manager."); + console.log("***********************************************"); + console.log("Issuer Account: " + Issuer.address + "\n"); + + await setup(); + try { + await selectST(); + await addPermissionModule(); + await changePermissionStep(); + } catch (err) { + console.log(err); + return; + } +}; + +async function setup(){ + try { + let securityTokenRegistryAddress = await contracts.securityTokenRegistry(); + let securityTokenRegistryABI = abis.securityTokenRegistry(); + securityTokenRegistry = new web3.eth.Contract(securityTokenRegistryABI, securityTokenRegistryAddress); + securityTokenRegistry.setProvider(web3.currentProvider); + } catch (err) { + console.log(err) + console.log('\x1b[31m%s\x1b[0m',"There was a problem getting the contracts. Make sure they are deployed to the selected network."); + process.exit(0); + } +} + +async function selectST() { + if (!tokenSymbol) + tokenSymbol = readlineSync.question('Enter the token symbol: '); + + let result = await securityTokenRegistry.methods.getSecurityTokenAddress(tokenSymbol).call(); + if (result == "0x0000000000000000000000000000000000000000") { + tokenSymbol = undefined; + console.log(chalk.red(`Token symbol provided is not a registered Security Token.`)); + await selectST(); + } else { + let securityTokenABI = abis.securityToken(); + securityToken = new web3.eth.Contract(securityTokenABI,result); + } +} + +async function addPermissionModule() { + let generalPermissionManagerAddress; + let result = await securityToken.methods.getModulesByName(web3.utils.toHex('GeneralPermissionManager')).call(); + if (result.length == 0) { + console.log(chalk.red(`General Permission Manager is not attached.`)); + if (readlineSync.keyInYNStrict('Do you want to add General Permission Manager Module to your Security Token?')) { + let permissionManagerFactoryAddress = await contracts.getModuleFactoryAddressByName(securityToken.options.address, MODULES_TYPES.PERMISSION, 'GeneralPermissionManager'); + let addModuleAction = securityToken.methods.addModule(permissionManagerFactoryAddress, web3.utils.fromAscii('', 16), 0, 0); + let receipt = await common.sendTransaction(Issuer, addModuleAction, defaultGasPrice); + let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'ModuleAdded'); + console.log(`Module deployed at address: ${event._module}`); + generalPermissionManagerAddress = event._module; + } else { + process.exit(0); + } + } else { + generalPermissionManagerAddress = result[0]; + } + + let generalPermissionManagerABI = abis.generalPermissionManager(); + generalPermissionManager = new web3.eth.Contract(generalPermissionManagerABI, generalPermissionManagerAddress); + generalPermissionManager.setProvider(web3.currentProvider); +} + +async function changePermissionStep() { + console.log('\n\x1b[34m%s\x1b[0m',"Permission Manager - Change Permission"); + let selectedDelegate = await selectDelegate(); + let selectedModule = await selectModule(); + let selectedPermission = await selectPermission(selectedModule.permissions); + let isValid = isPermissionValid(); + await changePermission(selectedDelegate, selectedModule.address, selectedPermission, isValid); +} + +// Helper functions +async function selectDelegate() { + let result; + let delegates = await getDelegates(); + + let options = ['Add new delegate']; + options = options.concat(delegates.map(function(d) { + return `Account: ${d.address} + Details: ${d.details}` + })); + + let index = readlineSync.keyInSelect(options, 'Select a delegate:', {cancel: false}); + if (index == 0) { + let newDelegate = await addNewDelegate(); + result = newDelegate; + } else { + result = delegates[index - 1].address; + } + + return result; +} + +async function selectModule() { + let modules = await getModulesWithPermissions(); + let options = modules.map(function(m) { + return m.name; + }); + let index = readlineSync.keyInSelect(options, 'Select a module:', {cancel: false}); + return modules[index]; +} + +async function selectPermission(permissions) { + let options = permissions.map(function(p) { + return p + }); + let index = readlineSync.keyInSelect(options, 'Select a permission:', {cancel: false}); + return permissions[index]; +} + +function isPermissionValid() { + let options = ['Grant permission', 'Revoke permission']; + let index = readlineSync.keyInSelect(options, 'What do you want to do?', {cancel: false}); + return index == 0; +} + +async function changePermission(delegate, moduleAddress, permission, isValid) { + let changePermissionAction = generalPermissionManager.methods.changePermission(delegate, moduleAddress, web3.utils.asciiToHex(permission), isValid); + let receipt = await common.sendTransaction(Issuer, changePermissionAction, defaultGasPrice, 0, 1.5); + common.getEventFromLogs(generalPermissionManager._jsonInterface, receipt.logs, 'ChangePermission'); + console.log(`Permission changed succesfully,`); +} + +async function getDelegates() { + let result = []; + /* + let events = await generalPermissionManager.getPastEvents('LogAddPermission', { fromBlock: 0}); + for (let event of events) { + let delegate = {}; + delegate.address = event.returnValues._delegate; + delegate.details = web3.utils.hexToAscii(event.returnValues._details); + result.push(delegate); + } + */ + let delegates = await generalPermissionManager.methods.getAllDelegates().call(); + for (let d of delegates) { + let delegate = {}; + delegate.address = d; + delegate.details = web3.utils.hexToAscii(await generalPermissionManager.methods.delegateDetails(d).call()); + result.push(delegate); + } + return result; +} + +async function addNewDelegate() { + let newDelegate = readlineSync.question('Enter the delegate address: ', { + limit: function (input) { + return web3.utils.isAddress(input); + }, + limitMessage: "Must be a valid address" + }); + let details = readlineSync.question('Enter the delegate details (i.e `Belongs to financial firm`): ', { + limit: function(input) { + return input.length > 0; + }, + limitMessage: "Must be a valid string" + }); + let addPermissionAction = generalPermissionManager.methods.addDelegate(newDelegate, web3.utils.asciiToHex(details)); + let receipt = await common.sendTransaction(Issuer, addPermissionAction, defaultGasPrice); + let event = common.getEventFromLogs(generalPermissionManager._jsonInterface, receipt.logs, 'AddDelegate'); + console.log(`Delegate added succesfully: ${event._delegate} - ${event._details}`); + return event._delegate; +} + +async function getModulesWithPermissions() { + let modules = []; + let moduleABI = abis.moduleInterface(); + + for (const type in MODULES_TYPES) { + let modulesAttached = await securityToken.methods.getModulesByType(MODULES_TYPES[type]).call(); + for (const m of modulesAttached) { + let contractTemp = new web3.eth.Contract(moduleABI, m); + let permissions = await contractTemp.methods.getPermissions().call(); + if (permissions.length > 0) { + modules.push({ + name: web3.utils.hexToAscii((await securityToken.methods.getModule(m).call())[0]), + address: m, + permissions: permissions.map(function (p) { return web3.utils.hexToAscii(p) }) + }) + } + } + } + + return modules; +} + +module.exports = { + executeApp: async function(remoteNetwork) { + return executeApp(remoteNetwork); + } +} \ No newline at end of file diff --git a/CLI/polymath-cli.js b/CLI/polymath-cli.js index 5ce0a455d..98c8d240d 100644 --- a/CLI/polymath-cli.js +++ b/CLI/polymath-cli.js @@ -11,6 +11,7 @@ var dividends_manager = require('./commands/dividends_manager'); var transfer_manager = require('./commands/transfer_manager'); var contract_manager = require('./commands/contract_manager'); var strMigrator = require('./commands/strMigrator'); +var permission_manager = require('./commands/permission_manager'); var program = require('commander'); const yaml = require('js-yaml'); const fs = require('fs'); @@ -142,6 +143,14 @@ program await strMigrator.executeApp(toStrAddress, fromTrAddress, fromStrAddress, program.remoteNode); }); +program + .command('permission_manager') + .alias('pm') + .description('Runs permission_manager') + .action(async function() { + await permission_manager.executeApp(program.remoteNode); + }); + program.parse(process.argv); if (typeof program.commands.length == 0) { diff --git a/README.md b/README.md index fc4498ecf..820fc8cf6 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ You can access Ethereum via the Infura load-balanced nodes. You have to save you node CLI/polymath-cli faucet --remote-node kovan ``` 3. Connected to a local private test network using `ganache-cli`. -You have to save the private key for the first account generated by ganache into `./privKeyLocal`. +You have to save the private key for the one of the accounts generated by ganache into `./privKeyLocal`. ## Poly Faucet From 06a1916f742f0fe26d5b5c3f9af10db8f921ef52 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 12 Oct 2018 19:50:15 +0530 Subject: [PATCH 133/142] Migrating to yarn from npm (#340) * Migrated from npm to yarn * Updated instructions * Added yarn to CLI * Added package-lock.json to gitignore --- .gitignore | 3 +- CHANGELOG.md | 1 + CLI/package-lock.json | 2531 --------- CLI/yarn.lock | 2347 +++++++++ README.md | 13 +- package-lock.json | 11275 ---------------------------------------- package.json | 5 +- yarn.lock | 2481 ++++++--- 8 files changed, 4102 insertions(+), 14554 deletions(-) delete mode 100644 CLI/package-lock.json create mode 100644 CLI/yarn.lock delete mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 2109c105f..5e131eaba 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ scTopics coverageEnv /flat /tempPoly -.eslintrc.js \ No newline at end of file +.eslintrc.js +package-lock.json \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2827a58a0..1a4896b14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. [__1.5.0__](https://www.npmjs.com/package/polymath-core?activeTab=readme) __15-08-18__ ## Added +* Migrated from `npm` to `yarn`. * Added `SingleTradeVolumeRestrictionManager` module * Added flag in `PercentageTransferManager` to allow ignoring of issuance transfers * Added `transferWithData`, `transferFromWithData`, `mintWithData`, `burnWithData` to allow passing of a `bytes _data` for off-chain validation diff --git a/CLI/package-lock.json b/CLI/package-lock.json deleted file mode 100644 index fd1d928a7..000000000 --- a/CLI/package-lock.json +++ /dev/null @@ -1,2531 +0,0 @@ -{ - "name": "polymath-cli", - "version": "1.4.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "requires": { - "mime-types": "2.1.20", - "negotiator": "0.6.1" - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "1.9.3" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "2.1.2" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "requires": { - "bn.js": "4.11.8", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "requires": { - "readable-stream": "2.3.6", - "safe-buffer": "5.1.2" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "2.0.3" - } - }, - "bluebird": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", - "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==" - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", - "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "1.6.16" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", - "safe-buffer": "5.1.2" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "1.2.0", - "browserify-des": "1.0.2", - "evp_bytestokey": "1.0.3" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.3", - "safe-buffer": "5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "requires": { - "bn.js": "4.11.8", - "randombytes": "2.0.6" - } - }, - "browserify-sha3": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", - "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", - "requires": { - "js-sha3": "0.3.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "elliptic": "6.4.1", - "inherits": "2.0.3", - "parse-asn1": "5.1.1" - } - }, - "buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "requires": { - "base64-js": "1.3.0", - "ieee754": "1.1.12" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "requires": { - "buffer-alloc-unsafe": "1.1.0", - "buffer-fill": "1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "requires": { - "delayed-stream": "1.0.0" - } - }, - "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", - "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", - "requires": { - "object-assign": "4.1.1", - "vary": "1.1.2" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.1" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", - "md5.js": "1.3.4", - "ripemd160": "2.0.2", - "sha.js": "2.4.11" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "inherits": "2.0.3", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.2", - "sha.js": "2.4.11" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "1.0.1", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.3", - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "diffie-hellman": "5.0.3", - "inherits": "2.0.3", - "pbkdf2": "3.0.16", - "public-encrypt": "4.0.2", - "randombytes": "2.0.6", - "randomfill": "1.0.4" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", - "requires": { - "decompress-tar": "4.1.1", - "decompress-tarbz2": "4.1.1", - "decompress-targz": "4.1.1", - "decompress-unzip": "4.0.1", - "graceful-fs": "4.1.11", - "make-dir": "1.3.0", - "pify": "2.3.0", - "strip-dirs": "2.1.0" - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "1.0.1" - } - }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "requires": { - "file-type": "5.2.0", - "is-stream": "1.1.0", - "tar-stream": "1.6.1" - } - }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "requires": { - "decompress-tar": "4.1.1", - "file-type": "6.2.0", - "is-stream": "1.1.0", - "seek-bzip": "1.0.5", - "unbzip2-stream": "1.2.5" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "requires": { - "decompress-tar": "4.1.1", - "file-type": "5.2.0", - "is-stream": "1.1.0" - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "requires": { - "file-type": "3.9.0", - "get-stream": "2.3.1", - "pify": "2.3.0", - "yauzl": "2.10.0" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "requires": { - "object-assign": "4.1.1", - "pinkie-promise": "2.0.1" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "4.11.8", - "miller-rabin": "4.0.1", - "randombytes": "2.0.6" - } - }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "optional": true, - "requires": { - "jsbn": "0.1.1", - "safer-buffer": "2.1.2" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", - "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0", - "hash.js": "1.1.5", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "1.4.0" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eth-lib": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", - "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", - "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.1", - "keccakjs": "0.2.1", - "nano-json-stream-parser": "0.1.2", - "servify": "0.1.12", - "ws": "3.3.3", - "xhr-request-promise": "0.1.2" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "eventemitter3": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", - "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "1.3.4", - "safe-buffer": "5.1.2" - } - }, - "express": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", - "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", - "requires": { - "accepts": "1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.2", - "content-disposition": "0.5.2", - "content-type": "1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "finalhandler": "1.1.1", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", - "qs": "6.5.1", - "range-parser": "1.2.0", - "safe-buffer": "5.1.1", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", - "utils-merge": "1.0.1", - "vary": "1.1.2" - }, - "dependencies": { - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", - "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", - "iconv-lite": "0.4.19", - "on-finished": "2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "1.6.16" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" - }, - "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.4.0" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - } - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "requires": { - "pend": "1.2.0" - } - }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" - }, - "dependencies": { - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - } - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "1.1.4" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.6", - "mime-types": "2.1.20" - }, - "dependencies": { - "combined-stream": { - "version": "1.0.6", - "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "requires": { - "delayed-stream": "1.0.0" - } - } - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" - } - }, - "fs-promise": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", - "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", - "requires": { - "any-promise": "1.3.0", - "fs-extra": "2.1.2", - "mz": "2.7.0", - "thenify-all": "1.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "requires": { - "min-document": "2.19.0", - "process": "0.5.2" - } - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "requires": { - "decompress-response": "3.3.0", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-plain-obj": "1.1.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "isurl": "1.0.0", - "lowercase-keys": "1.0.1", - "p-cancelable": "0.3.0", - "p-timeout": "1.2.1", - "safe-buffer": "5.1.2", - "timed-out": "4.0.1", - "url-parse-lax": "1.0.0", - "url-to-options": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", - "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "1.4.2" - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" - } - }, - "hash.js": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", - "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "1.1.5", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "requires": { - "depd": "1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": "1.5.0" - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.14.2" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "requires": { - "safer-buffer": "2.1.2" - } - }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" - }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "requires": { - "has-to-string-tag-x": "1.4.1", - "is-object": "1.0.1" - } - }, - "js-sha3": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", - "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "4.1.11" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccakjs": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", - "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", - "requires": { - "browserify-sha3": "0.0.1", - "sha3": "1.2.2" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "requires": { - "pify": "3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - } - } - }, - "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", - "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" - }, - "mime-db": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", - "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" - }, - "mime-types": { - "version": "2.1.20", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", - "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", - "requires": { - "mime-db": "1.36.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "0.1.1" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.11" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "requires": { - "mkdirp": "0.5.1" - } - }, - "mock-fs": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.6.0.tgz", - "integrity": "sha512-aYutNIwFaMsVgtMoc5vMsobA/yRJR2FTUFoTZgnjdb3gID0g8WMmeafWmHPgzKgZ7zwQ5kggYUgeq5sN9k9uDw==" - }, - "moment": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" - }, - "mout": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", - "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "requires": { - "any-promise": "1.3.0", - "object-assign": "4.1.1", - "thenify-all": "1.6.0" - } - }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "oboe": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", - "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", - "requires": { - "http-https": "1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "requires": { - "p-finally": "1.0.0" - } - }, - "parse-asn1": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", - "requires": { - "asn1.js": "4.10.1", - "browserify-aes": "1.2.0", - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.16" - } - }, - "parse-headers": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", - "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", - "requires": { - "for-each": "0.3.3", - "trim": "0.0.1" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "pbkdf2": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", - "requires": { - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.2", - "sha.js": "2.4.11" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "2.0.4" - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", - "requires": { - "forwarded": "0.1.2", - "ipaddr.js": "1.8.0" - } - }, - "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" - }, - "public-encrypt": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", - "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.2.0", - "parse-asn1": "5.1.1", - "randombytes": "2.0.6" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "0.2.0", - "object-assign": "4.1.1", - "strict-uri-encode": "1.1.0" - } - }, - "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "2.0.6", - "safe-buffer": "5.1.2" - } - }, - "randomhex": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz", - "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=" - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } - }, - "readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=" - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.7", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.1.0", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.20", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.4.3", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" - } - }, - "request-promise": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", - "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", - "requires": { - "bluebird": "3.5.2", - "request-promise-core": "1.1.1", - "stealthy-require": "1.1.1", - "tough-cookie": "2.4.3" - } - }, - "request-promise-core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", - "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", - "requires": { - "lodash": "4.17.11" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "requires": { - "glob": "7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scrypt": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", - "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", - "requires": { - "nan": "2.10.0" - } - }, - "scrypt.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", - "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", - "requires": { - "scrypt": "6.0.3", - "scryptsy": "1.2.1" - } - }, - "scryptsy": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", - "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", - "requires": { - "pbkdf2": "3.0.16" - } - }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", - "requires": { - "commander": "2.8.1" - }, - "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "requires": { - "graceful-readlink": "1.0.1" - } - } - } - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "requires": { - "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "fresh": "0.5.2", - "http-errors": "1.6.3", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" - }, - "dependencies": { - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - } - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.16.2" - } - }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "requires": { - "body-parser": "1.18.3", - "cors": "2.8.4", - "express": "4.16.3", - "request": "2.88.0", - "xhr": "2.5.0" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" - } - }, - "sha3": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", - "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", - "requires": { - "nan": "2.10.0" - } - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" - }, - "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "requires": { - "decompress-response": "3.3.0", - "once": "1.4.0", - "simple-concat": "1.0.0" - } - }, - "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "requires": { - "asn1": "0.2.4", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.2", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.2", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "safer-buffer": "2.1.2", - "tweetnacl": "0.14.5" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "requires": { - "is-natural-number": "4.0.1" - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "3.0.0" - } - }, - "swarm-js": { - "version": "0.1.37", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", - "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", - "requires": { - "bluebird": "3.5.2", - "buffer": "5.2.1", - "decompress": "4.2.0", - "eth-lib": "0.1.27", - "fs-extra": "2.1.2", - "fs-promise": "2.0.3", - "got": "7.1.0", - "mime-types": "2.1.20", - "mkdirp-promise": "5.0.1", - "mock-fs": "4.6.0", - "setimmediate": "1.0.5", - "tar.gz": "1.0.7", - "xhr-request-promise": "0.1.2" - } - }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", - "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", - "requires": { - "bl": "1.2.2", - "buffer-alloc": "1.2.0", - "end-of-stream": "1.4.1", - "fs-constants": "1.0.0", - "readable-stream": "2.3.6", - "to-buffer": "1.1.1", - "xtend": "4.0.1" - } - }, - "tar.gz": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", - "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", - "requires": { - "bluebird": "2.11.0", - "commander": "2.16.0", - "fstream": "1.0.11", - "mout": "0.11.1", - "tar": "2.2.1" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" - } - } - }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "requires": { - "any-promise": "1.3.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "requires": { - "thenify": "3.3.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "1.1.29", - "punycode": "1.4.1" - } - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true - }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.20" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "1.0.0" - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "unbzip2-stream": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", - "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", - "requires": { - "buffer": "3.6.0", - "through": "2.3.8" - }, - "dependencies": { - "base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=" - }, - "buffer": { - "version": "3.6.0", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", - "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", - "requires": { - "base64-js": "0.0.8", - "ieee754": "1.1.12", - "isarray": "1.0.0" - } - } - } - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "1.0.4" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" - }, - "utf8": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", - "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - } - }, - "web3": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.35.tgz", - "integrity": "sha512-xwDmUhvTcHQvvNnOPcPZZgCxKUsI2e+GbHy7JkTK3/Rmnutazy8x7fsAXT9myw7V1qpi3GgLoZ3fkglSUbg1Mg==", - "requires": { - "web3-bzz": "1.0.0-beta.35", - "web3-core": "1.0.0-beta.35", - "web3-eth": "1.0.0-beta.35", - "web3-eth-personal": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35", - "web3-shh": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-bzz": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.35.tgz", - "integrity": "sha512-BhAU0qhlr8zltm4gs/+P1gki2VkxHJaM2Rrh4DGesDW0lzwufRoNvWFlwx1bKHoFPWNbSmm9PRkHOYOINL/Tgw==", - "requires": { - "got": "7.1.0", - "swarm-js": "0.1.37", - "underscore": "1.8.3" - } - }, - "web3-core": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.35.tgz", - "integrity": "sha512-ayGavbgVk4KL9Y88Uv411fBJ0SVgVfKhKEBweKYzmP0zOqneMzWt6YsyD1n6kRvjAbqA0AfUPEOKyMNjcx2tjw==", - "requires": { - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-requestmanager": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-core-helpers": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.35.tgz", - "integrity": "sha512-APOu3sEsamyqWt//8o4yq9KF25/uqGm+pQShson/sC4gKzmfJB07fLo2ond0X30E8fIqAPeVCotPXQxGciGUmA==", - "requires": { - "underscore": "1.8.3", - "web3-eth-iban": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-core-method": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.35.tgz", - "integrity": "sha512-jidImCide8q0GpfsO4L73qoHrbkeWgwU3uOH5DKtJtv0ccmG086knNMRgryb/o9ZgetDWLmDEsJnHjBSoIwcbA==", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-promievent": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-core-promievent": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.35.tgz", - "integrity": "sha512-GvqXqKq07OmHuVi5uNRg6k79a1/CI0ViCC+EtNv4CORHtDRmYEt5Bvdv6z6FJEiaaQkD0lKbFwNhLxutx7HItw==", - "requires": { - "any-promise": "1.3.0", - "eventemitter3": "1.1.1" - } - }, - "web3-core-requestmanager": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.35.tgz", - "integrity": "sha512-S+zW2h17ZZQU9oe3yaCJE0E7aJS4C3Kf4kGPDv+nXjW0gKhQQhgVhw1Doq/aYQGqNSWJp7f1VHkz5gQWwg6RRg==", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "web3-providers-http": "1.0.0-beta.35", - "web3-providers-ipc": "1.0.0-beta.35", - "web3-providers-ws": "1.0.0-beta.35" - } - }, - "web3-core-subscriptions": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.35.tgz", - "integrity": "sha512-gXzLrWvcGkGiWq1y33Z4Y80XI8XMrwowiQJkrPSjQ81K5PBKquOGwcMffLaKcwdmEy/NpsOXDeFo3eLE1Ghvvw==", - "requires": { - "eventemitter3": "1.1.1", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35" - } - }, - "web3-eth": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.35.tgz", - "integrity": "sha512-04mcb2nGPXThawuuYICPOxv0xOHofvQKsjZeIq+89nyOC8DQMGTAErDkGyMHQYtjpth5XDhic0wuEsA80AmFZA==", - "requires": { - "underscore": "1.8.3", - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-eth-abi": "1.0.0-beta.35", - "web3-eth-accounts": "1.0.0-beta.35", - "web3-eth-contract": "1.0.0-beta.35", - "web3-eth-iban": "1.0.0-beta.35", - "web3-eth-personal": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-eth-abi": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.35.tgz", - "integrity": "sha512-KUDC+EtFFYG8z01ZleKrASdjj327/rtWHzEt6RWsEj7bBa0bGp9nEh+nqdZx/Sdgz1O8tnfFzJlrRcXpfr1vGg==", - "requires": { - "bn.js": "4.11.6", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "web3-eth-accounts": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.35.tgz", - "integrity": "sha512-duIgRsfht/0kAW/eQ0X9lKtVIykbETrnM2H7EnvplCzPHtQLodpib4o9JXfh9n6ZDgdDC7cuJoiVB9QJg089ew==", - "requires": { - "any-promise": "1.3.0", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.7", - "scrypt.js": "0.2.0", - "underscore": "1.8.3", - "uuid": "2.0.1", - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", - "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", - "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.1", - "xhr-request-promise": "0.1.2" - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" - } - } - }, - "web3-eth-contract": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.35.tgz", - "integrity": "sha512-foPohOg5O1UCGKGZOIs+kQK5IZdV2QQ7pAWwNxH8WHplUA+fre1MurXNpoxknUmH6mYplFhXjqgYq2MsrBpHrA==", - "requires": { - "underscore": "1.8.3", - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-promievent": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-eth-abi": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-eth-iban": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.35.tgz", - "integrity": "sha512-H5wkcNcAIc+h/WoDIKv7ZYmrM2Xqu3O7jBQl1IWo73EDVQji+AoB2i3J8tuwI1yZRInRwrfpI3Zuwuf54hXHmQ==", - "requires": { - "bn.js": "4.11.6", - "web3-utils": "1.0.0-beta.35" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "web3-eth-personal": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.35.tgz", - "integrity": "sha512-AcM9nnlxu7ZRRxPvkrFB9eLxMM4A2cPfj2aCg21Wb2EpMnhR+b/O1cT33k7ApRowoMpM+T9M8vx2oPNwXfaCOQ==", - "requires": { - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-net": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.35.tgz", - "integrity": "sha512-bbwaQ/KohGjIJ6HAKbZ6KrklCAaG6/B7hIbAbVLSFLxF+Yz9lmAgQYaDInpidpC/NLb3WOmcbRF+P77J4qMVIA==", - "requires": { - "web3-core": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-providers-http": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.35.tgz", - "integrity": "sha512-DcIMFq52Fb08UpWyZ3ZlES6NsNqJnco4hBS/Ej6eOcASfuUayPI+GLkYVZsnF3cBYqlH+DOKuArcKSuIxK7jIA==", - "requires": { - "web3-core-helpers": "1.0.0-beta.35", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.35.tgz", - "integrity": "sha512-iB0FG0HcpUnayfa8pn4guqEQ4Y1nrroi/jffdtQgFkrNt0sD3fMSwwC0AbmECqj3tDLl0e1slBR0RENll+ZF0g==", - "requires": { - "oboe": "2.1.3", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35" - } - }, - "web3-providers-ws": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.35.tgz", - "integrity": "sha512-Cx64NgDStynKaUGDIIOfaCd0fZusL8h5avKTkdTjUu2aHhFJhZoVBGVLhoDtUaqZGWIZGcBJOoVf2JkGUOjDRQ==", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" - } - }, - "web3-shh": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.35.tgz", - "integrity": "sha512-8qSonk/x0xabERS9Sr6AIADN/Ty+5KwARkkGIfSYHKqFpdMDz+76F7cUCxtoCZoS8K04xgZlDKYe0TJXLYA0Fw==", - "requires": { - "web3-core": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35" - } - }, - "web3-utils": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.35.tgz", - "integrity": "sha512-Dq6f0SOKj3BDFRgOPnE6ALbzBDCKVIW8mKWVf7tGVhTDHf+wQaWwQSC3aArFSqdExB75BPBPyDpuMTNszhljpA==", - "requires": { - "bn.js": "4.11.6", - "eth-lib": "0.1.27", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randomhex": "0.1.5", - "underscore": "1.8.3", - "utf8": "2.1.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "websocket": { - "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", - "requires": { - "debug": "2.6.9", - "nan": "2.10.0", - "typedarray-to-buffer": "3.1.5", - "yaeti": "0.0.6" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "requires": { - "async-limiter": "1.0.0", - "safe-buffer": "5.1.2", - "ultron": "1.1.1" - } - }, - "xhr": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", - "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", - "requires": { - "global": "4.3.2", - "is-function": "1.0.1", - "parse-headers": "2.0.1", - "xtend": "4.0.1" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "requires": { - "buffer-to-arraybuffer": "0.0.5", - "object-assign": "4.1.1", - "query-string": "5.1.1", - "simple-get": "2.8.1", - "timed-out": "4.0.1", - "url-set-query": "1.0.0", - "xhr": "2.5.0" - } - }, - "xhr-request-promise": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", - "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", - "requires": { - "xhr-request": "1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "requires": { - "cookiejar": "2.1.2" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.1.0" - } - } - } -} diff --git a/CLI/yarn.lock b/CLI/yarn.lock new file mode 100644 index 000000000..4a06bda2e --- /dev/null +++ b/CLI/yarn.lock @@ -0,0 +1,2347 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@^10.3.2": + version "10.11.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.7.tgz#0e75ca9357d646ca754016ca1d68a127ad7e7300" + integrity sha512-yOxFfkN9xUFLyvWaeYj90mlqTJ41CsQzWKS3gXdOMOyPVacUsymejKxJ4/pMW7exouubuEeZLJawGgcNGYlTeg== + +accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +aes-js@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= + +ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +any-promise@1.3.0, any-promise@^1.0.0, any-promise@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" + integrity sha1-EQHpVE9KdrG8OybUUsqW16NeeXg= + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bl@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^2.9.34: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= + +bluebird@^3.5.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" + integrity sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg== + +bn.js@4.11.6: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.6, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.18.3, body-parser@^1.16.0: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sha3@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/browserify-sha3/-/browserify-sha3-0.0.1.tgz#3ff34a3006ef15c0fb3567e541b91a2340123d11" + integrity sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE= + dependencies: + js-sha3 "^0.3.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^3.0.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-3.6.0.tgz#a72c936f77b96bf52f5f7e7b467180628551defb" + integrity sha1-pyyTb3e5a/UvX357RnGAYoVR3vs= + dependencies: + base64-js "0.0.8" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.0.5: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +combined-stream@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + integrity sha1-cj599ugBrFYTETp+RFqbactjKBg= + dependencies: + delayed-stream "~1.0.0" + +combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.16.0, commander@^2.8.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commander@~2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookiejar@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cors@^2.8.1: + version "2.8.4" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" + integrity sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY= + dependencies: + object-assign "^4" + vary "^1" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +crypto-browserify@3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" + integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50= + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +elliptic@6.3.3: + version "6.3.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" + integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8= + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + inherits "^2.0.1" + +elliptic@^6.0.0, elliptic@^6.4.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eth-ens-namehash@2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88= + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + +eth-lib@0.1.27, eth-lib@^0.1.26: + version "0.1.27" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.27.tgz#f0b0fd144f865d2d6bf8257a40004f2e75ca1dd6" + integrity sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + keccakjs "^0.2.1" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + +eth-lib@0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca" + integrity sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco= + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +ethers@4.0.0-beta.1: + version "4.0.0-beta.1" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.1.tgz#0648268b83e0e91a961b1af971c662cdf8cbab6d" + integrity sha512-SoYhktEbLxf+fiux5SfCEwdzWENMvgIbMZD90I62s4GZD9nEjgEWy8ZboI3hck193Vs0bDoTohDISx84f2H2tw== + dependencies: + "@types/node" "^10.3.2" + aes-js "3.0.0" + bn.js "^4.4.0" + elliptic "6.3.3" + hash.js "1.1.3" + js-sha3 "0.5.7" + scrypt-js "2.0.3" + setimmediate "1.0.4" + uuid "2.0.1" + xmlhttprequest "1.8.0" + +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +eventemitter3@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.1.1.tgz#47786bdaa087caf7b1b75e73abc5c7d540158cd0" + integrity sha1-R3hr2qCHyvext15zq8XH1UAVjNA= + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +express@^4.14.0: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha1-LdvqfHP/42No365J3DOMBYwritY= + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +for-each@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + integrity sha1-SXBJi+YEwgwAXU9cI67NIda0kJk= + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^2.0.0, fs-extra@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35" + integrity sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + +fs-promise@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-2.0.3.tgz#f64e4f854bcf689aa8bddcba268916db3db46854" + integrity sha1-9k5PhUvPaJqovdy6JokW2z20aFQ= + dependencies: + any-promise "^1.3.0" + fs-extra "^2.0.0" + mz "^2.6.0" + thenify-all "^1.6.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fstream@^1.0.2, fstream@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob@^7.0.5: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@~4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +got@7.1.0, got@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" + integrity sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA== + dependencies: + ajv "^5.3.0" + har-schema "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= + +is-callable@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-function@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= + +is-hex-prefixed@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= + +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +js-sha3@0.5.7, js-sha3@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= + +js-sha3@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243" + integrity sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +keccakjs@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.1.tgz#1d633af907ef305bbf9f2fa616d56c44561dfa4d" + integrity sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0= + dependencies: + browserify-sha3 "^0.0.1" + sha3 "^1.1.0" + +lodash@^4.13.1: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" + integrity sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw== + +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.18, mime-types@~2.1.19: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + integrity sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A== + dependencies: + mime-db "~1.36.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= + dependencies: + mkdirp "*" + +mkdirp@*, "mkdirp@>=0.5 0": + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mock-fs@^4.1.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.7.0.tgz#9f17e219cacb8094f4010e0a8c38589e2b33c299" + integrity sha512-WlQNtUlzMRpvLHf8dqeUmNqfdPjGY29KrJF50Ldb4AcL+vQeR8QH3wQcFMgrhTwb1gHjZn9xggho+84tBskLgA== + +moment@^2.22.2: + version "2.22.2" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" + integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= + +mout@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/mout/-/mout-0.11.1.tgz#ba3611df5f0e5b1ffbfd01166b8f02d1f5fa2b99" + integrity sha1-ujYR318OWx/7/QEWa48C0fX6K5k= + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +mz@^2.6.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nan@2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== + +nan@^2.0.8, nan@^2.3.3: + version "2.11.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +number-to-bn@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= + dependencies: + bn.js "4.11.6" + strip-hex-prefix "1.0.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +oboe@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.3.tgz#2b4865dbd46be81225713f4e9bfe4bcf4f680a4f" + integrity sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8= + dependencies: + http-https "^1.0.0" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= + dependencies: + p-finally "^1.0.0" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-headers@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" + integrity sha1-aug6eqJanZtwCswoaYzR8e1+lTY= + dependencies: + for-each "^0.3.2" + trim "0.0.1" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +qs@6.5.2, qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +randomhex@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/randomhex/-/randomhex-0.1.5.tgz#baceef982329091400f2a2912c6cd02f1094f585" + integrity sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU= + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +readable-stream@^2.3.0, readable-stream@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readline-sync@^1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.9.tgz#3eda8e65f23cd2a17e61301b1f0003396af5ecda" + integrity sha1-PtqOZfI80qF+YTAbHwADOWr17No= + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY= + dependencies: + lodash "^4.13.1" + +request-promise@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" + integrity sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ= + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@^2.79.0, request@^2.88.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +rimraf@2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +scrypt-js@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" + integrity sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q= + +scrypt.js@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.2.0.tgz#af8d1465b71e9990110bedfc593b9479e03a8ada" + integrity sha1-r40UZbcemZARC+38WTuUeeA6ito= + dependencies: + scrypt "^6.0.2" + scryptsy "^1.2.1" + +scrypt@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" + integrity sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0= + dependencies: + nan "^2.0.8" + +scryptsy@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" + integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= + dependencies: + pbkdf2 "^3.0.3" + +seek-bzip@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= + dependencies: + commander "~2.8.1" + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + +setimmediate@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" + integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +sha3@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.2.tgz#a66c5098de4c25bc88336ec8b4817d005bca7ba9" + integrity sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k= + dependencies: + nan "2.10.0" + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^2.7.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" + integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +sshpk@^1.7.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.1.tgz#b79a089a732e346c6e0714830f36285cd38191a2" + integrity sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + +strip-hex-prefix@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= + dependencies: + is-hex-prefixed "1.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +swarm-js@0.1.37: + version "0.1.37" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.37.tgz#27d485317a340bbeec40292af783cc10acfa4663" + integrity sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + decompress "^4.0.0" + eth-lib "^0.1.26" + fs-extra "^2.1.2" + fs-promise "^2.0.0" + got "^7.1.0" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar.gz "^1.0.5" + xhr-request-promise "^0.1.2" + +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar.gz@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/tar.gz/-/tar.gz-1.0.7.tgz#577ef2c595faaa73452ef0415fed41113212257b" + integrity sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg== + dependencies: + bluebird "^2.9.34" + commander "^2.8.1" + fstream "^1.0.8" + mout "^0.11.0" + tar "^2.1.1" + +tar@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +thenify-all@^1.0.0, thenify-all@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.0" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= + dependencies: + any-promise "^1.0.0" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +tough-cookie@>=2.3.3, tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray-to-buffer@^3.1.2: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + +unbzip2-stream@^1.0.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1" + integrity sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw== + dependencies: + buffer "^3.0.1" + through "^2.3.6" + +underscore@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI= + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +utf8@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.1.tgz#2e01db02f7d8d0944f77104f1609eb0c304cf768" + integrity sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g= + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" + integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= + +uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +web3-bzz@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.0.0-beta.36.tgz#adb3fe7a70053eb7843e32b106792b01b482ef41" + integrity sha512-clDRS/ziboJ5ytnrfxq80YSu9HQsT0vggnT3BkoXadrauyEE/9JNLxRu016jjUxqdkfdv4MgIPDdOS3Bv2ghiw== + dependencies: + got "7.1.0" + swarm-js "0.1.37" + underscore "1.8.3" + +web3-core-helpers@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.36.tgz#6f618e80f1a6588d846efbfdc28f92ae0477f8d2" + integrity sha512-gu74l0htiGWuxLQuMnZqKToFvkSM+UFPE7qUuy1ZosH/h2Jd+VBWg6k4CyNYVYfP0hL5x3CN8SBmB+HMowo55A== + dependencies: + underscore "1.8.3" + web3-eth-iban "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-core-method@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.36.tgz#855c0365ae7d0ead394d973ea9e28828602900e0" + integrity sha512-dJsP3KkGaqBBSdxfzvLsYPOmVaSs1lR/3oKob/gtUYG7UyTnwquwliAc7OXj+gqRA2E/FHZcM83cWdl31ltdSA== + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.36" + web3-core-promievent "1.0.0-beta.36" + web3-core-subscriptions "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-core-promievent@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.36.tgz#3a5127787fff751be6de272722cbc77dc9523fd5" + integrity sha512-RGIL6TjcOeJTullFLMurChPTsg94cPF6LI763y/sPYtXTDol1vVa+J5aGLp/4WW8v+s+1bSQO6zYq2ZtkbmtEQ== + dependencies: + any-promise "1.3.0" + eventemitter3 "1.1.1" + +web3-core-requestmanager@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.36.tgz#70c8eead84da9ed1cf258e6dde3f137116d0691b" + integrity sha512-/CHuaMbiMDu1v8ANGYI7yFCnh1GaCWx5pKnUPJf+QTk2xAAw+Bvd97yZJIWPOK5AOPUIzxgwx9Ob/5ln6mTmYA== + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.36" + web3-providers-http "1.0.0-beta.36" + web3-providers-ipc "1.0.0-beta.36" + web3-providers-ws "1.0.0-beta.36" + +web3-core-subscriptions@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.36.tgz#20f1f20c85d5b40f1e5a49b070ba977a142621f3" + integrity sha512-/evyLQ8CMEYXC5aUCodDpmEnmGVYQxaIjiEIfA/85f9ifHkfzP1aOwCAjcsLsJWnwrWDagxSpjCYrDtnNabdEw== + dependencies: + eventemitter3 "1.1.1" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.36" + +web3-core@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.36.tgz#86182f2456c2cf1cd6e7654d314e195eac211917" + integrity sha512-C2QW9CMMRZdYAiKiLkMrKRSp+gekSqTDgZTNvlxAdN1hXn4d9UmcmWSJXOmIHqr5N2ISbRod+bW+qChODxVE3Q== + dependencies: + web3-core-helpers "1.0.0-beta.36" + web3-core-method "1.0.0-beta.36" + web3-core-requestmanager "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-eth-abi@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.36.tgz#21c0f222701db827a8a269accb9cd18bbd8f70f9" + integrity sha512-fBfW+7hvA0rxEMV45fO7JU+0R32ayT7aRwG9Cl6NW2/QvhFeME2qVbMIWw0q5MryPZGIN8A6366hKNuWvVidDg== + dependencies: + ethers "4.0.0-beta.1" + underscore "1.8.3" + web3-utils "1.0.0-beta.36" + +web3-eth-accounts@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.36.tgz#8aea37df9b038ef2c6cda608856ffd861b39eeef" + integrity sha512-MmgIlBEZ0ILLWV4+wfMrbeVVMU/VmQnCpgSDcw7wHKOKu47bKncJ6rVqVsUbC6d9F613Rios+Yj2Ua6SCHtmrg== + dependencies: + any-promise "1.3.0" + crypto-browserify "3.12.0" + eth-lib "0.2.7" + scrypt.js "0.2.0" + underscore "1.8.3" + uuid "2.0.1" + web3-core "1.0.0-beta.36" + web3-core-helpers "1.0.0-beta.36" + web3-core-method "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-eth-contract@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.36.tgz#c0c366c4e4016896142208cee758a2ff2a31be2a" + integrity sha512-cywqcIrUsCW4fyqsHdOb24OCC8AnBol8kNiptI+IHRylyCjTNgr53bUbjrXWjmEnear90rO0QhAVjLB1a4iEbQ== + dependencies: + underscore "1.8.3" + web3-core "1.0.0-beta.36" + web3-core-helpers "1.0.0-beta.36" + web3-core-method "1.0.0-beta.36" + web3-core-promievent "1.0.0-beta.36" + web3-core-subscriptions "1.0.0-beta.36" + web3-eth-abi "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-eth-ens@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.0.0-beta.36.tgz#c7440b42b597fd74f64bc402f03ad2e832f423d8" + integrity sha512-8ZdD7XoJfSX3jNlZHSLe4G837xQ0v5a8cHCcDcd1IoqoY855X9SrIQ0Xdqia9p4mR1YcH1vgmkXY9/3hsvxS7g== + dependencies: + eth-ens-namehash "2.0.8" + underscore "1.8.3" + web3-core "1.0.0-beta.36" + web3-core-helpers "1.0.0-beta.36" + web3-core-promievent "1.0.0-beta.36" + web3-eth-abi "1.0.0-beta.36" + web3-eth-contract "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-eth-iban@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.36.tgz#00cb3aba7a5aeb15d02b07421042e263d7b2e01b" + integrity sha512-b5AEDjjhOLR4q47Hbzf65zYE+7U7JgCgrUb13RU4HMIGoMb1q4DXaJw1UH8VVHCZulevl2QBjpCyrntecMqqCQ== + dependencies: + bn.js "4.11.6" + web3-utils "1.0.0-beta.36" + +web3-eth-personal@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.36.tgz#95545998a8ee377e3bb71e27c8d1a5dc1d7d5a21" + integrity sha512-+oxvhojeWh4C/XtnlYURWRR3F5Cg7bQQNjtN1ZGnouKAZyBLoYDVVJ6OaPiveNtfC9RKnzLikn9/Uqc0xz410A== + dependencies: + web3-core "1.0.0-beta.36" + web3-core-helpers "1.0.0-beta.36" + web3-core-method "1.0.0-beta.36" + web3-net "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-eth@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.36.tgz#04a8c748d344c1accaa26d7d5d0eac0da7127f14" + integrity sha512-uEa0UnbnNHUB4N2O1U+LsvxzSPJ/w3azy5115IseaUdDaiz6IFFgFfFP3ssauayQNCf7v2F44GXLfPhrNeb/Sw== + dependencies: + underscore "1.8.3" + web3-core "1.0.0-beta.36" + web3-core-helpers "1.0.0-beta.36" + web3-core-method "1.0.0-beta.36" + web3-core-subscriptions "1.0.0-beta.36" + web3-eth-abi "1.0.0-beta.36" + web3-eth-accounts "1.0.0-beta.36" + web3-eth-contract "1.0.0-beta.36" + web3-eth-ens "1.0.0-beta.36" + web3-eth-iban "1.0.0-beta.36" + web3-eth-personal "1.0.0-beta.36" + web3-net "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-net@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.36.tgz#396cd35cb40934ed022a1f44a8a642d3908c41eb" + integrity sha512-BriXK0Pjr6Hc/VDq1Vn8vyOum4JB//wpCjgeGziFD6jC7Of8YaWC7AJYXje89OckzfcqX1aJyJlBwDpasNkAzQ== + dependencies: + web3-core "1.0.0-beta.36" + web3-core-method "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +web3-providers-http@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.36.tgz#c1937a2e64f8db7cd30f166794e37cf0fcca1131" + integrity sha512-KLSqMS59nRdpet9B0B64MKgtM3n9wAHTcAHJ03hv79avQNTjHxtjZm0ttcjcFUPpWDgTCtcYCa7tqaYo9Pbeog== + dependencies: + web3-core-helpers "1.0.0-beta.36" + xhr2-cookies "1.1.0" + +web3-providers-ipc@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.36.tgz#0c78efb4ed6b0305ec830e1e0b785e61217ee605" + integrity sha512-iEUrmdd2CzoWgp+75/ydom/1IaoLw95qkAzsgwjjZp1waDncHP/cvVGX74+fbUx4hRaPdchyzxCQfNpgLDmNjQ== + dependencies: + oboe "2.1.3" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.36" + +web3-providers-ws@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.36.tgz#27b74082c7adfa0cb5a65535eb312e49008c97c3" + integrity sha512-wAnENuZx75T5ZSrT2De2LOaUuPf2yRjq1VfcbD7+Zd79F3DZZLBJcPyCNVQ1U0fAXt0wfgCKl7sVw5pffqR9Bw== + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.36" + websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" + +web3-shh@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.36.tgz#6ff297594480edefc710d9d287765a0c4a5d5af1" + integrity sha512-bREGHS/WprYFSvGUhyIk8RSpT2Z5SvJOKGBrsUW2nDIMWO6z0Op8E7fzC6GXY2HZfZliAqq6LirbXLgcLRWuPw== + dependencies: + web3-core "1.0.0-beta.36" + web3-core-method "1.0.0-beta.36" + web3-core-subscriptions "1.0.0-beta.36" + web3-net "1.0.0-beta.36" + +web3-utils@1.0.0-beta.36: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.36.tgz#dc19c9aeec009b1816cc91ef64d7fe9f8ee344c9" + integrity sha512-7ri74lG5fS2Th0fhYvTtiEHMB1Pmf2p7dQx1COQ3OHNI/CHNEMjzoNMEbBU6FAENrywfoFur40K4m0AOmEUq5A== + dependencies: + bn.js "4.11.6" + eth-lib "0.1.27" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randomhex "0.1.5" + underscore "1.8.3" + utf8 "2.1.1" + +web3@^1.0.0-beta.35: + version "1.0.0-beta.36" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.36.tgz#2954da9e431124c88396025510d840ba731c8373" + integrity sha512-fZDunw1V0AQS27r5pUN3eOVP7u8YAvyo6vOapdgVRolAu5LgaweP7jncYyLINqIX9ZgWdS5A090bt+ymgaYHsw== + dependencies: + web3-bzz "1.0.0-beta.36" + web3-core "1.0.0-beta.36" + web3-eth "1.0.0-beta.36" + web3-eth-personal "1.0.0-beta.36" + web3-net "1.0.0-beta.36" + web3-shh "1.0.0-beta.36" + web3-utils "1.0.0-beta.36" + +"websocket@git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible": + version "1.0.26" + resolved "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" + dependencies: + debug "^2.2.0" + nan "^2.3.3" + typedarray-to-buffer "^3.1.2" + yaeti "^0.0.6" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +xhr-request-promise@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz#343c44d1ee7726b8648069682d0f840c83b4261d" + integrity sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0= + dependencies: + xhr-request "^1.0.1" + +xhr-request@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= + dependencies: + cookiejar "^2.1.1" + +xhr@^2.0.4, xhr@^2.3.3: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xmlhttprequest@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= + +yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" diff --git a/README.md b/README.md index 820fc8cf6..88f2407ec 100644 --- a/README.md +++ b/README.md @@ -209,12 +209,11 @@ node CLI/polymath-cli dividends_manager ## Package version requirements for your machine: - Homebrew v1.6.7 -- node v9.11.1 -- npm v5.6.0 -- Yarn v1.7.0 +- node v8.x.x or v9.x.x +- Yarn v1.3 or newer - Truffle v4.1.11 (core: 4.1.11) - Solidity v0.4.24 (solc-js) -- Ganache CLI v6.1.3 (ganache-core: 2.1.2) +- Ganache CLI v6.1.3 (ganache-core: 2.1.2) or newer ## Setup @@ -222,10 +221,10 @@ The smart contracts are written in [Solidity](https://github.com/ethereum/solidi ```bash # Install Truffle package globally: -$ npm install -g truffle +$ yarn global add truffle # Install local node dependencies: -$ npm install +$ yarn install ``` ## Testing @@ -233,7 +232,7 @@ $ npm install To test the code simply run: ```bash -$ npm run test +$ yarn run test ``` diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index f6b236627..000000000 --- a/package-lock.json +++ /dev/null @@ -1,11275 +0,0 @@ -{ - "name": "polymath-core", - "version": "1.4.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@soldoc/markdown": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@soldoc/markdown/-/markdown-0.1.0.tgz", - "integrity": "sha512-V0UnvVVJ1qDzpuKLMuh7oHG94puwi8BI3t99Vrr7dQgIHuJdfZJ4SbGuWuFV/fSthyH++WY4ePO3d6gxfZ2//w==", - "dev": true - }, - "@soldoc/soldoc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@soldoc/soldoc/-/soldoc-0.4.3.tgz", - "integrity": "sha1-JP/ukmQijhw+3WH9MWLWNYeVSTM=", - "dev": true, - "requires": { - "@soldoc/markdown": "^0.1.0", - "chalk": "^2.3.1", - "deep-assign": "^2.0.0", - "fs-extra": "^5.0.0", - "shelljs": "^0.8.1", - "solc": "^0.4.19", - "valid-url": "^1.0.9", - "yargs": "^11.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "abstract-leveldown": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", - "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", - "requires": { - "xtend": "~4.0.0" - } - }, - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" - } - }, - "acorn": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==" - }, - "acorn-dynamic-import": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", - "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", - "requires": { - "acorn": "^4.0.3" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" - } - } - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "aes-js": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", - "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=" - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "ambi": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ambi/-/ambi-2.5.0.tgz", - "integrity": "sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA=", - "dev": true, - "requires": { - "editions": "^1.1.1", - "typechecker": "^4.3.0" - }, - "dependencies": { - "typechecker": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-4.5.0.tgz", - "integrity": "sha512-bqPE/ck3bVIaXP7gMKTKSHrypT32lpYTpiqzPYeYzdSQnmaGvaGhy7TnN/M/+5R+2rs/kKcp9ZLPRp/Q9Yj+4w==", - "dev": true, - "requires": { - "editions": "^1.3.4" - } - } - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-escapes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", - "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arguments-extended": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/arguments-extended/-/arguments-extended-0.0.3.tgz", - "integrity": "sha1-YQfkkX0OtvCk3WYyD8Fa/HLvSUY=", - "dev": true, - "requires": { - "extended": "~0.0.3", - "is-extended": "~0.0.8" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-extended": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/array-extended/-/array-extended-0.0.11.tgz", - "integrity": "sha1-1xRK50jek8pybxIQCdv/FibRZL0=", - "dev": true, - "requires": { - "arguments-extended": "~0.0.3", - "extended": "~0.0.3", - "is-extended": "~0.0.3" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" - }, - "async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "requires": { - "async": "^2.4.0" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - } - } - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "babel-core": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", - "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.0", - "debug": "^2.6.8", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.7", - "slash": "^1.0.0", - "source-map": "^0.5.6" - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" - } - } - }, - "babel-helper-bindify-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", - "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-explode-class": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", - "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", - "requires": { - "babel-helper-bindify-decorators": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" - }, - "babel-plugin-syntax-async-generators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", - "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=" - }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" - }, - "babel-plugin-syntax-decorators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=" - }, - "babel-plugin-syntax-dynamic-import": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", - "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" - }, - "babel-plugin-transform-async-generator-functions": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", - "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-generators": "^6.5.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", - "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", - "requires": { - "babel-helper-explode-class": "^6.24.1", - "babel-plugin-syntax-decorators": "^6.13.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", - "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - } - }, - "babel-preset-env": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", - "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^2.1.2", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" - } - }, - "babel-preset-stage-2": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", - "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", - "requires": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", - "babel-preset-stage-3": "^6.24.1" - } - }, - "babel-preset-stage-3": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", - "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", - "requires": { - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-exponentiation-operator": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.22.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - } - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babelify": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", - "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", - "requires": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, - "base-x": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", - "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=" - }, - "base64-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", - "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==" - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" - }, - "bignumber.js": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-5.0.0.tgz", - "integrity": "sha512-KWTu6ZMVk9sxlDJQh2YH1UOnfDP8O8TpxUxgQG/vKASoSnEjK9aVuOueFaPcQEYQ5fyNXNTOYwYw3099RYebWg==" - }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" - }, - "bindings": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bitcore-lib": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-0.15.0.tgz", - "integrity": "sha512-AeXLWhiivF6CDFzrABZHT4jJrflyylDWTi32o30rF92HW9msfuKpjzrHtFKYGa9w0kNVv5HABQjCB3OEav4PhQ==", - "dev": true, - "requires": { - "bn.js": "=4.11.8", - "bs58": "=4.0.1", - "buffer-compare": "=1.1.1", - "elliptic": "=6.4.0", - "inherits": "=2.0.1", - "lodash": "=4.17.4" - }, - "dependencies": { - "base-x": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz", - "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - } - } - }, - "bitcore-mnemonic": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bitcore-mnemonic/-/bitcore-mnemonic-1.5.0.tgz", - "integrity": "sha512-sbeP4xwkindLMfIQhVxj6rZSDMwtiKmfc1DqvwpR6Yg+Qo4I4WHO5pvzb12Y04uDh1N3zgD45esHhfH0HHmE4g==", - "dev": true, - "requires": { - "bitcore-lib": "^0.15.0", - "unorm": "^1.3.3" - } - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" - }, - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - }, - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", - "iconv-lite": "0.4.19", - "on-finished": "~2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "~1.6.15" - } - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.x.x" - } - }, - "borc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/borc/-/borc-2.0.3.tgz", - "integrity": "sha512-2mfipKUXn7yLgwn8D5jZkJqd2ZyzqmYZQX/9d4On33oGNDLwxj5qQMst+nkKyEdaujQRFfrZCId+k8wehQVANg==", - "dev": true, - "requires": { - "bignumber.js": "^6.0.0", - "commander": "^2.15.0", - "ieee754": "^1.1.8", - "json-text-sequence": "^0.1" - }, - "dependencies": { - "bignumber.js": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-6.0.0.tgz", - "integrity": "sha512-x247jIuy60/+FtMRvscqfxtVHQf8AGx2hm9c6btkgC0x/hp9yt+teISNhvF8WlwRkCc5yF2fDECH8SIMe8j+GA==", - "dev": true - }, - "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "browserify-aes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", - "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", - "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", - "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sha3": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", - "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", - "requires": { - "js-sha3": "^0.3.1" - }, - "dependencies": { - "js-sha3": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", - "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=" - } - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", - "requires": { - "caniuse-lite": "^1.0.30000792", - "electron-to-chromium": "^1.3.30" - } - }, - "bs58": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", - "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", - "requires": { - "base-x": "^1.1.0" - } - }, - "bs58check": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", - "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", - "requires": { - "bs58": "^3.1.0", - "create-hash": "^1.1.0" - } - }, - "bson": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", - "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==", - "dev": true, - "optional": true - }, - "buffer": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", - "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-compare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz", - "integrity": "sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY=", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, - "buffer-from": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", - "dev": true - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" - }, - "caminte": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/caminte/-/caminte-0.3.7.tgz", - "integrity": "sha1-7B7ARXZkoPCSZDt8ZGxFfVzW9pM=", - "dev": true, - "requires": { - "bluebird": "^3.4.6", - "uuid": "^3.0.1" - } - }, - "caniuse-lite": { - "version": "1.0.30000819", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000819.tgz", - "integrity": "sha512-9i1d8eiKA6dLvsMrVrXOTP9/1sd9iIv4iC/UbPbIa9iQd9Gcnozi2sQ0d69TiQY9l7Alt7YIWISOBwyGSM6H0Q==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "checkpoint-store": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", - "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", - "requires": { - "functional-red-black-tree": "^1.0.1" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "cli-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.2.0.tgz", - "integrity": "sha1-OlrnT9drYmevZm5p4q+70B3vNNE=", - "dev": true, - "requires": { - "ansi-regex": "^2.1.1", - "d": "1", - "es5-ext": "^0.10.12", - "es6-iterator": "2", - "memoizee": "^0.4.3", - "timers-ext": "0.1" - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", - "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "coinstring": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", - "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", - "requires": { - "bs58": "^2.0.1", - "create-hash": "^1.1.1" - }, - "dependencies": { - "bs58": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", - "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=" - } - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "requires": { - "color-name": "^1.1.1" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "colors": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", - "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", - "dev": true - }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", - "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==" - }, - "compare-versions": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz", - "integrity": "sha512-MAAAIOdi2s4Gl6rZ76PNcUa9IOYB+5ICdT41o5uMRf09aEu/F9RK+qhe8RjXNPwcTjGV7KU7h2P/fljThFVqyQ==", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "requires": { - "date-now": "^0.1.4" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=" - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "core-js": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", - "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", - "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "coveralls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", - "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", - "requires": { - "js-yaml": "^3.6.1", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.5", - "minimist": "^1.2.0", - "request": "^2.79.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "create-ecdh": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", - "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cron-parser": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-2.5.0.tgz", - "integrity": "sha512-gzmXu16/prizIbKPPKJo+WgBpV7k8Rxxu9FgaANW+vx5DebCXavfRqbROjKkr9ETvVPqs+IO+NXj4GG/eLf8zQ==", - "dev": true, - "requires": { - "is-nan": "^1.2.1", - "moment-timezone": "^0.5.0" - } - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "requires": { - "boom": "5.x.x" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.x.x" - } - } - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-js": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", - "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=" - }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "csextends": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/csextends/-/csextends-1.2.0.tgz", - "integrity": "sha512-S/8k1bDTJIwuGgQYmsRoE+8P+ohV32WhQ0l4zqrc0XDdxOhjQQD7/wTZwCzoZX53jSX3V/qwjT+OkPTxWQcmjg==", - "dev": true - }, - "cycle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", - "dev": true - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "requires": { - "es5-ext": "^0.10.9" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-extended": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/date-extended/-/date-extended-0.0.6.tgz", - "integrity": "sha1-I4AtV90b94GIE/4MMuhRqG2iZ8k=", - "dev": true, - "requires": { - "array-extended": "~0.0.3", - "extended": "~0.0.3", - "is-extended": "~0.0.3" - } - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "declare.js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/declare.js/-/declare.js-0.0.8.tgz", - "integrity": "sha1-BHit/5VkwAT1Hfc9i8E0AZ0o3N4=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - } - }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "deep-assign": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-2.0.0.tgz", - "integrity": "sha1-6+BrHwfwja5ZdiDj3RYi83GhxXI=", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deferred-leveldown": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", - "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - }, - "dependencies": { - "object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" - } - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "dependencies": { - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delimit-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", - "integrity": "sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "requires": { - "repeating": "^2.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", - "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "eachr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/eachr/-/eachr-2.0.4.tgz", - "integrity": "sha1-Rm98qhBwj2EFCeMsgHqv5X/BIr8=", - "dev": true, - "requires": { - "typechecker": "^2.0.8" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron-to-chromium": { - "version": "1.3.40", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.40.tgz", - "integrity": "sha1-H71tl779crim+SHcONIkE9L2/d8=" - }, - "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", - "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "es5-ext": { - "version": "0.10.39", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.39.tgz", - "integrity": "sha512-AlaXZhPHl0po/uxMx1tyrlt1O86M6D5iVaDH8UgLfgek4kXTX6vzsRfJQWC2Ku+aG8pkw1XWzh9eTkwfVrsD5g==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.4.0.tgz", - "integrity": "sha512-Dyzmifil8n/TmSqYDEXbm+C8yitzJQqQIlJQLNRMwa+BOUJpRC19pyVeN12JAjt61xonvXjtff+hJruTRXn5HA==", - "dev": true - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "eslint-config-standard": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz", - "integrity": "sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - } - }, - "eslint-module-utils": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", - "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^1.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.10.0.tgz", - "integrity": "sha1-+gkIPVp1KI35xsfQn+EiVZhWVec=", - "dev": true, - "requires": { - "builtin-modules": "^1.1.1", - "contains-path": "^0.1.0", - "debug": "^2.6.8", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "eslint-plugin-node": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", - "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", - "dev": true, - "requires": { - "ignore": "^3.3.6", - "minimatch": "^3.0.4", - "resolve": "^1.3.3", - "semver": "^5.4.1" - } - }, - "eslint-plugin-promise": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz", - "integrity": "sha512-2WO+ZFh7vxUKRfR0cOIMrWgYKdR6S1AlOezw6pC52B6oYpd5WFghN+QHxvrRdZMtbo8h3dfUZ2o1rWb0UPbKtg==", - "dev": true - }, - "eslint-plugin-standard": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", - "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", - "dev": true - }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eth-block-tracker": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-2.3.0.tgz", - "integrity": "sha512-yrNyBIBKC7WfUjrXSG/CZVy0gW2aF8+MnjnrkOxkZOR+BAtL6JgYOnzVnrU8KE6mKJETlA/1dYMygvLXWyJGGw==", - "requires": { - "async-eventemitter": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "async-eventemitter": { - "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "from": "async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "requires": { - "async": "^2.4.0" - } - }, - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "eth-lib": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", - "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "keccakjs": "^0.2.1", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "eth-lightwallet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-lightwallet/-/eth-lightwallet-3.0.1.tgz", - "integrity": "sha512-79vVCETy+4l1b6wuOWwjqPW3Bom5ZK46BgkUNwaXhiMG1rrMRHjpjYEWMqH0JHeCzOzB4HBIFz7eK1/4s6w5nA==", - "dev": true, - "requires": { - "bitcore-lib": "^0.15.0", - "bitcore-mnemonic": "^1.5.0", - "buffer": "^4.9.0", - "crypto-js": "^3.1.5", - "elliptic": "^3.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.1", - "rlp": "^2.0.0", - "scrypt-async": "^1.2.0", - "tweetnacl": "0.13.2", - "web3": "0.20.2" - }, - "dependencies": { - "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "dev": true - }, - "bn.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-2.2.0.tgz", - "integrity": "sha1-EhYrwq5x/EClYmwzQ486h1zTdiU=", - "dev": true - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "elliptic": { - "version": "3.1.0", - "resolved": "http://registry.npmjs.org/elliptic/-/elliptic-3.1.0.tgz", - "integrity": "sha1-whaC73YnabVqdCAWCRBdoR1fYMw=", - "dev": true, - "requires": { - "bn.js": "^2.0.3", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" - } - }, - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - } - } - }, - "tweetnacl": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.2.tgz", - "integrity": "sha1-RTFhdwRp1FzSZsNkBOK8maj6mUQ=", - "dev": true - }, - "web3": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.2.tgz", - "integrity": "sha1-xU2sX8DjdzmcBMGm7LsS5FEyeNY=", - "dev": true, - "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" - } - } - } - }, - "eth-query": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", - "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", - "requires": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "eth-sig-util": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", - "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "ethereumjs-util": "^5.1.1" - }, - "dependencies": { - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereum-bridge": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/ethereum-bridge/-/ethereum-bridge-0.6.1.tgz", - "integrity": "sha512-yDTivI85618BoLI71yNRzW6iVcVN2rjnviCIzs0QOCOENj4XpYQhMDGhdqDi8XWDdzTd0Ja/Canuuh3vfE2IcA==", - "dev": true, - "requires": { - "async": "^2.4.1", - "borc": "^2.0.2", - "caminte": "0.3.7", - "colors": "^1.1.2", - "compare-versions": "^3.0.1", - "crypto-random-string": "^1.0.0", - "eth-lightwallet": "^3.0.1", - "ethereumjs-abi": "0.6.4", - "ethereumjs-tx": "^1.3.1", - "ethereumjs-util": "^5.2.0", - "i18n": "^0.8.3", - "moment": "^2.22.2", - "multihashes": "^0.4.5", - "node-async-loop": "^1.2.2", - "node-cache": "^4.1.1", - "node-schedule": "^1.2.3", - "pragma-singleton": "1.0.3", - "request": "^2.81.0", - "semver": "^5.5.0", - "stdio": "^0.2.7", - "tingodb": "^0.6.1", - "underscore": "^1.8.3", - "utf8": "^2.1.2", - "web3": "0.19.1", - "winston": "^2.3.1" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "bignumber.js": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", - "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==", - "dev": true - }, - "ethereumjs-abi": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.4.tgz", - "integrity": "sha1-m6G7BWSS0AwnJ59uzNTVgnWRLBo=", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", - "dev": true, - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", - "dev": true - }, - "utf8": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", - "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=", - "dev": true - }, - "web3": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.19.1.tgz", - "integrity": "sha1-52PVsRB8S8JKvU+MvuG6Nlnm6zE=", - "dev": true, - "requires": { - "bignumber.js": "^4.0.2", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" - } - } - } - }, - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" - }, - "ethereumjs-abi": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz", - "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - } - }, - "ethereumjs-account": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.4.tgz", - "integrity": "sha1-+MMCMby3B/RRTYoFLB+doQNiTUc=", - "requires": { - "ethereumjs-util": "^4.0.1", - "rlp": "^2.0.0" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", - "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereumjs-testrpc": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ethereumjs-testrpc/-/ethereumjs-testrpc-6.0.3.tgz", - "integrity": "sha512-lAxxsxDKK69Wuwqym2K49VpXtBvLEsXr1sryNG4AkvL5DomMdeCBbu3D87UEevKenLHBiT8GTjARwN6Yj039gA==", - "requires": { - "webpack": "^3.0.0" - } - }, - "ethereumjs-testrpc-sc": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.1.6.tgz", - "integrity": "sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg==", - "dev": true, - "requires": { - "source-map-support": "^0.5.3" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "ethereumjs-tx": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz", - "integrity": "sha512-kOgUd5jC+0tgV7t52UDECMMz9Uf+Lro+6fSpCvzWemtXfMEcwI3EOxf5mVPMRbTFkMMhuERokNNVF3jItAjidg==", - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereum-common": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" - }, - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" - } - }, - "ethereumjs-vm": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.3.tgz", - "integrity": "sha512-yIWJqTEcrF9vJTCvNMxacRkAx6zIZTOW0SmSA+hSFiU1x8JyVZDi9o5udwsRVECT5RkPgQzm62kpL6Pf4qemsw==", - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereum-common": "0.2.0", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~1.7.0", - "ethereumjs-util": "^5.1.3", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.1.1", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereumjs-wallet": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", - "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", - "requires": { - "aes-js": "^0.2.3", - "bs58check": "^1.0.8", - "ethereumjs-util": "^4.4.0", - "hdkey": "^0.7.0", - "scrypt.js": "^0.2.0", - "utf8": "^2.1.1", - "uuid": "^2.0.1" - }, - "dependencies": { - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" - } - } - }, - "ethers": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-3.0.15.tgz", - "integrity": "sha512-d/tiMUavaeaY2GFqjpgfPzT46cEc0cilP3hnlTXR3LR/HR5Qrhv4PfdgW3gxBlR5aBTtUeM/lo8z8ph3JdtFhQ==", - "requires": { - "aes-js": "3.0.0", - "bn.js": "^4.4.0", - "elliptic": "6.3.3", - "hash.js": "^1.0.0", - "inherits": "2.0.1", - "js-sha3": "0.5.7", - "scrypt-js": "2.0.3", - "setimmediate": "1.0.4", - "uuid": "2.0.1", - "xmlhttprequest": "1.8.0" - }, - "dependencies": { - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, - "elliptic": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", - "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" - } - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - }, - "setimmediate": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=" - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" - } - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - } - }, - "ethjs-util": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.4.tgz", - "integrity": "sha1-HItoeSV0RO9NPz+7rC3tEs2ZfZM=", - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "eventemitter3": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", - "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=" - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "express": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", - "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", - "requires": { - "accepts": "~1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.2", - "content-disposition": "0.5.2", - "content-type": "~1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.1.1", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.3", - "qs": "6.5.1", - "range-parser": "~1.2.0", - "safe-buffer": "5.1.1", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - } - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extended": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/extended/-/extended-0.0.6.tgz", - "integrity": "sha1-f7i/e52uOXWG5IVwrP1kLHjlBmk=", - "dev": true, - "requires": { - "extender": "~0.0.5" - } - }, - "extender": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/extender/-/extender-0.0.10.tgz", - "integrity": "sha1-WJwHSCvmGhRgttgfnCSqZ+jzJM0=", - "dev": true, - "requires": { - "declare.js": "~0.0.4" - } - }, - "extendr": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/extendr/-/extendr-2.1.0.tgz", - "integrity": "sha1-MBqgu+pWX00tyPVw8qImEahSe1Y=", - "dev": true, - "requires": { - "typechecker": "~2.0.1" - }, - "dependencies": { - "typechecker": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-2.0.8.tgz", - "integrity": "sha1-6D2oS7ZMWEzLNFg4V2xAsDN9uC4=", - "dev": true - } - } - }, - "external-editor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", - "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "extract-opts": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/extract-opts/-/extract-opts-2.2.0.tgz", - "integrity": "sha1-H6KOunNSxttID4hc63GkaBC+bX0=", - "dev": true, - "requires": { - "typechecker": "~2.0.1" - }, - "dependencies": { - "typechecker": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-2.0.8.tgz", - "integrity": "sha1-6D2oS7ZMWEzLNFg4V2xAsDN9uC4=", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", - "dev": true - }, - "fake-merkle-patricia-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", - "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", - "requires": { - "checkpoint-store": "^1.1.0" - } - }, - "fast-csv": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-2.4.1.tgz", - "integrity": "sha1-vX3SaDkfcpNntZRFuN0K0CaIGyY=", - "dev": true, - "requires": { - "extended": "0.0.6", - "is-extended": "0.0.10", - "object-extended": "0.0.7", - "string-extended": "0.0.8" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fbjs": { - "version": "0.8.17", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", - "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", - "dev": true, - "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - }, - "dependencies": { - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", - "dev": true - } - } - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "requires": { - "pend": "~1.2.0" - } - }, - "fetch-ponyfill": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", - "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", - "requires": { - "node-fetch": "~1.7.1" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^1.1.3", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", - "unpipe": "~1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" - } - }, - "for-each": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", - "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", - "requires": { - "is-function": "~1.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", - "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-promise": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", - "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", - "requires": { - "any-promise": "^1.3.0", - "fs-extra": "^2.0.0", - "mz": "^2.6.0", - "thenify-all": "^1.6.0" - }, - "dependencies": { - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", - "optional": true, - "requires": { - "nan": "^2.3.0", - "node-pre-gyp": "^0.6.39" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "optional": true, - "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "aproba": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "optional": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "~2.0.0" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "requires": { - "hoek": "2.x.x" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "requires": { - "balanced-match": "^0.4.1", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "requires": { - "boom": "2.x.x" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "optional": true, - "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "optional": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.39", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "hawk": "3.1.3", - "mkdirp": "^0.5.1", - "nopt": "^4.0.1", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "request": "2.81.0", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^2.2.1", - "tar-pack": "^3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "optional": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" - } - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true - }, - "semver": { - "version": "5.3.0", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "requires": { - "hoek": "2.x.x" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "optional": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jodid25519": "^1.0.0", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "^2.2.0", - "fstream": "^1.0.10", - "fstream-ignore": "^1.0.5", - "once": "^1.3.3", - "readable-stream": "^2.1.4", - "rimraf": "^2.5.1", - "tar": "^2.2.1", - "uid-number": "^0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "optional": true, - "requires": { - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - } - } - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "ganache-cli": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.1.8.tgz", - "integrity": "sha512-yXzteu4SIgUL31mnpm9j+x6dpHUw0p/nsRVkcySKq0w+1vDxH9jMErP1QhZAJuTVE6ni4nfvGSNkaQx5cD3jfg==", - "dev": true, - "requires": { - "source-map-support": "^0.5.3" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" - }, - "handlebars": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", - "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", - "dev": true, - "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "requires": { - "function-bind": "^1.0.2" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", - "requires": { - "inherits": "^2.0.1" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "requires": { - "boom": "4.x.x", - "cryptiles": "3.x.x", - "hoek": "4.x.x", - "sntp": "2.x.x" - } - }, - "hdkey": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", - "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", - "requires": { - "coinstring": "^2.0.0", - "secp256k1": "^3.0.1" - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==" - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" - } - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, - "i18n": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.3.tgz", - "integrity": "sha1-LYzxwkciYCwgQdAbpq5eqlE4jw4=", - "dev": true, - "requires": { - "debug": "*", - "make-plural": "^3.0.3", - "math-interval-parser": "^1.1.0", - "messageformat": "^0.3.1", - "mustache": "*", - "sprintf-js": ">=1.0.3" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" - }, - "ieee754": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.10.tgz", - "integrity": "sha512-byWFX8OyW/qeVxcY21r6Ncxl0ZYHgnf0cPup2h34eHXrCJbOp7IuqnJ4Q0omfyWl6Z++BTI6bByf31pZt7iRLg==" - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "ignorefs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ignorefs/-/ignorefs-1.2.0.tgz", - "integrity": "sha1-2ln7hYl25KXkNwLM0fKC/byeV1Y=", - "dev": true, - "requires": { - "editions": "^1.3.3", - "ignorepatterns": "^1.1.0" - } - }, - "ignorepatterns": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ignorepatterns/-/ignorepatterns-1.1.0.tgz", - "integrity": "sha1-rI9DbyI5td+2bV8NOpBKh6xnzF4=", - "dev": true - }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" - }, - "invariant": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", - "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "ipaddr.js": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", - "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extended": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/is-extended/-/is-extended-0.0.10.tgz", - "integrity": "sha1-JE4UDfdbscmjEG9BL/GC+1NKbWI=", - "dev": true, - "requires": { - "extended": "~0.0.3" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz", - "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-nan": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.2.1.tgz", - "integrity": "sha1-n69ltvttskt/XAYoR16nH5iEAeI=", - "dev": true, - "requires": { - "define-properties": "^1.1.1" - } - }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" - }, - "is-odd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", - "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" - } - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "dev": true, - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", - "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "js-sha3": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.5.tgz", - "integrity": "sha1-uvDA6MVK1ZA0R9+Wreekobynmko=" - }, - "js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - }, - "js-yaml": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", - "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - }, - "json-loader": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" - }, - "json-rpc-engine": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.6.1.tgz", - "integrity": "sha512-xYuD9M1pcld5OKPzVAoEG5MKtnR8iKMyNzRpeS3/mCJ7dcAcS67vqfOmYLoaIQfVRU5uClThbjri3VFR0vEwYg==", - "requires": { - "async": "^2.0.1", - "babel-preset-env": "^1.3.2", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - } - } - }, - "json-rpc-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", - "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", - "requires": { - "inherits": "^2.0.1" - } - }, - "json-rpc-random-id": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz", - "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json-text-sequence": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", - "integrity": "sha1-py8hfcSvxGKf/1/rME3BvVGi89I=", - "dev": true, - "requires": { - "delimit-stream": "0.1.0" - } - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", - "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", - "requires": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" - } - }, - "keccakjs": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", - "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", - "requires": { - "browserify-sha3": "^0.0.1", - "sha3": "^1.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=" - }, - "level-codec": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", - "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" - }, - "level-errors": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", - "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, - "level-ws": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", - "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - }, - "dependencies": { - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" - } - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "loader-runner": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", - "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=" - }, - "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" - }, - "long-timeout": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", - "integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=", - "dev": true - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" - }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "requires": { - "js-tokens": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" - }, - "lru-cache": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", - "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "ltgt": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.0.tgz", - "integrity": "sha1-tlul/LNJopkkyOMz98alVi8uSEI=" - }, - "make-dir": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", - "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", - "requires": { - "pify": "^3.0.0" - } - }, - "make-plural": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-3.0.6.tgz", - "integrity": "sha1-IDOgO6wpC487uRJY9lud9+iwHKc=", - "dev": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-interval-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-1.1.0.tgz", - "integrity": "sha1-2+2lsGsySZc8bfYXD94jhvCv2JM=", - "dev": true, - "requires": { - "xregexp": "^2.0.0" - } - }, - "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "memdown": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", - "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "memoizee": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.12.tgz", - "integrity": "sha512-sprBu6nwxBWBvBOh5v2jcsGqiGLlL2xr2dLub3vR8dnE8YB17omwtm/0NSHl8jjNbcsJd5GMWJAnTSVe/O0Wfg==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.30", - "es6-weak-map": "^2.0.2", - "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.2" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "merkle-patricia-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", - "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - } - } - }, - "messageformat": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-0.3.1.tgz", - "integrity": "sha1-5Y//gkXps5cXmeW0PbWLPpQX9aI=", - "dev": true, - "requires": { - "async": "~1.5.2", - "glob": "~6.0.4", - "make-plural": "~3.0.3", - "nopt": "~3.0.6", - "watchr": "~2.4.13" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "requires": { - "mime-db": "~1.33.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - }, - "mimic-response": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", - "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=" - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "requires": { - "mkdirp": "*" - } - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, - "mock-fs": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.4.2.tgz", - "integrity": "sha512-dF+yxZSojSiI8AXGoxj5qdFWpucndc54Ug+TwlpHFaV7j22MGG+OML2+FVa6xAZtjb/OFFQhOC37Jegx2GbEwA==" - }, - "moment": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", - "dev": true - }, - "moment-timezone": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.21.tgz", - "integrity": "sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A==", - "dev": true, - "requires": { - "moment": ">= 2.9.0" - } - }, - "mout": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", - "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "multihashes": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.13.tgz", - "integrity": "sha512-HwJGEKPCpLlNlgGQA56CYh/Wsqa+c4JAq8+mheIgw7OK5T4QvNJqgp6TH8gZ4q4l1aiWeNat/H/MrFXmTuoFfQ==", - "dev": true, - "requires": { - "bs58": "^4.0.1", - "varint": "^5.0.0" - }, - "dependencies": { - "base-x": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz", - "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - } - } - }, - "mustache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.0.tgz", - "integrity": "sha1-QCj3d4sXcIpImTCm5SrDvKDaQdA=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nan": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.9.2.tgz", - "integrity": "sha512-ltW65co7f3PQWBDbqVvaU1WtFJUsNW7sWWm4HINhbMQIyVyzIeyZ8toX5TC5eeooE6piZoaEh4cZkueSKG3KYw==" - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" - }, - "nanomatch": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-odd": "^2.0.0", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" - }, - "neo-async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.0.tgz", - "integrity": "sha512-nJmSswG4As/MkRq7QZFuH/sf/yuv8ODdMZrY4Bedjp77a5MK4A6s7YbBB64c9u79EBUOfXUXBvArmvzTD0X+6g==" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "node-async-loop": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/node-async-loop/-/node-async-loop-1.2.2.tgz", - "integrity": "sha1-xYcCmb9kd7eAyItDGqWzdzP1Wj0=", - "dev": true - }, - "node-cache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.2.0.tgz", - "integrity": "sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw==", - "dev": true, - "requires": { - "clone": "2.x", - "lodash": "4.x" - }, - "dependencies": { - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - } - } - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^1.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.10.3", - "vm-browserify": "0.0.4" - }, - "dependencies": { - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - } - } - }, - "node-schedule": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-1.3.0.tgz", - "integrity": "sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A==", - "dev": true, - "requires": { - "cron-parser": "^2.4.0", - "long-timeout": "0.1.1", - "sorted-array-functions": "^1.0.0" - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - } - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-extended": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/object-extended/-/object-extended-0.0.7.tgz", - "integrity": "sha1-hP0j9WsVWCrrPoiwXLVdJDLWijM=", - "dev": true, - "requires": { - "array-extended": "~0.0.4", - "extended": "~0.0.3", - "is-extended": "~0.0.3" - } - }, - "object-inspect": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.5.0.tgz", - "integrity": "sha512-UmOFbHbwvv+XHj7BerrhVq+knjceBdkvU5AriwLMvhv2qi+e7DJzxfBeFpILEjVzCp+xA+W/pIf06RGPWlZNfw==" - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "oboe": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", - "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "openzeppelin-solidity": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/openzeppelin-solidity/-/openzeppelin-solidity-1.10.0.tgz", - "integrity": "sha512-igkrumQQ2lrN2zjeQV4Dnb0GpTBj1fzMcd8HPyBUqwI0hhuscX/HzXiqKT6gFQl1j9Wy/ppVVs9fqL/foF7Gmg==" - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "original-require": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", - "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=", - "dev": true - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", - "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "pako": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" - }, - "parse-asn1": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", - "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-headers": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", - "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", - "requires": { - "for-each": "^0.3.2", - "trim": "0.0.1" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "pbkdf2": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", - "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pegjs": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "pragma-singleton": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pragma-singleton/-/pragma-singleton-1.0.3.tgz", - "integrity": "sha1-aJQxe7jUcVflneKkoAnbfm9j4w4=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "requires": { - "asap": "~2.0.3" - } - }, - "promise-to-callback": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", - "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", - "requires": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - } - }, - "prop-types": { - "version": "15.6.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", - "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", - "dev": true, - "requires": { - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "proxy-addr": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", - "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.6.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "public-encrypt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", - "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" - }, - "query-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.0.tgz", - "integrity": "sha512-F3DkxxlY0AqD/rwe4YAwjRE2HjOkKW7TxsuteyrS/Jbwrxw887PqYBL4sWUJ9D/V1hmFns0SCD6FDyvlwo9RCQ==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" - }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "randomhex": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz", - "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=" - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" - }, - "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "unpipe": "1.0.0" - } - }, - "react": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/react/-/react-16.4.2.tgz", - "integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==", - "dev": true, - "requires": { - "fbjs": "^0.8.16", - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.0" - } - }, - "react-dom": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.2.tgz", - "integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==", - "dev": true, - "requires": { - "fbjs": "^0.8.16", - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.0" - } - }, - "readable-stream": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", - "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" - } - }, - "readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=" - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, - "regenerate": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", - "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==" - }, - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "requires": { - "jsesc": "~0.5.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "req-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-1.0.1.tgz", - "integrity": "sha1-DXOurpJm5penj3l2AZZ352rPD/8=", - "dev": true, - "requires": { - "req-from": "^1.0.1" - } - }, - "req-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/req-from/-/req-from-1.0.1.tgz", - "integrity": "sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4=", - "dev": true, - "requires": { - "resolve-from": "^2.0.0" - } - }, - "request": { - "version": "2.85.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", - "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "hawk": "~6.0.2", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "stringstream": "~0.0.5", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - } - } - }, - "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "requires": { - "path-parse": "^1.0.5" - } - }, - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "requires": { - "through": "~2.3.4" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" - }, - "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", - "requires": { - "hash-base": "^2.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.0.0.tgz", - "integrity": "sha1-nbOE/0uJqPYVY9kjldhiWxjzr7A=" - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rustbn.js": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.1.2.tgz", - "integrity": "sha512-bAkNqSHYdJdFsBC7Z11JgzYktL31HIpB2o70jZcGiL1U1TVtPyvaVhDrGWwS8uZtaqwW2k6NOPGZCqW/Dgh5Lg==" - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, - "safe": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/safe/-/safe-0.4.6.tgz", - "integrity": "sha1-HVWAzyY1xcuUDqSPtQga48JbG+E=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "safefs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/safefs/-/safefs-3.2.2.tgz", - "integrity": "sha1-gXDBRE1wOOCMrqBaN0+uL6NJ4Vw=", - "dev": true, - "requires": { - "graceful-fs": "*" - } - }, - "scandirectory": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/scandirectory/-/scandirectory-2.5.0.tgz", - "integrity": "sha1-bOA/VKCQtmjjy+2/IO354xBZPnI=", - "dev": true, - "requires": { - "ignorefs": "^1.0.0", - "safefs": "^3.1.2", - "taskgroup": "^4.0.5" - } - }, - "scrypt": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", - "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", - "requires": { - "nan": "^2.0.8" - } - }, - "scrypt-async": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-1.3.1.tgz", - "integrity": "sha1-oR/W+smBtLgj7gHe4CIRaVAN2uk=", - "dev": true - }, - "scrypt-js": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz", - "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=" - }, - "scrypt.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", - "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", - "requires": { - "scrypt": "^6.0.2", - "scryptsy": "^1.2.1" - } - }, - "scryptsy": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", - "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", - "requires": { - "pbkdf2": "^3.0.3" - } - }, - "secp256k1": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", - "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", - "requires": { - "bindings": "^1.2.1", - "bip66": "^1.1.3", - "bn.js": "^4.11.3", - "create-hash": "^1.1.2", - "drbg.js": "^1.0.1", - "elliptic": "^6.2.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" - } - }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", - "requires": { - "commander": "~2.8.1" - }, - "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "requires": { - "graceful-readlink": ">= 1.0.0" - } - } - } - }, - "semaphore": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", - "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - }, - "sha.js": { - "version": "2.4.10", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", - "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.0.tgz", - "integrity": "sha1-aYnxtwpJhwWHajc+LGKs6WqpOZo=", - "requires": { - "nan": "^2.0.5" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "shelljs": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", - "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" - }, - "simple-get": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz", - "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - } - }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "requires": { - "hoek": "4.x.x" - } - }, - "sol-digger": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/sol-digger/-/sol-digger-0.0.2.tgz", - "integrity": "sha1-QGxKnTHiaef4jrHC6hATGOXgkCU=", - "dev": true - }, - "sol-explore": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.1.tgz", - "integrity": "sha1-tZ8HPGn+MyVg1aEMMrqMp/KYbPs=", - "dev": true - }, - "sol-merger": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/sol-merger/-/sol-merger-0.1.2.tgz", - "integrity": "sha512-12Z84jxeb5VFlQOGS38HOiTrHYohU07oQ5wHOcFJmcRRbaL5kWN7IcldMO1QdW8kONyKdj0xhukzLlN5m5ix4w==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "cli-color": "^1.2.0", - "commander": "^2.11.0", - "debug": "^3.0.1", - "fs-extra": "^4.0.2", - "glob": "^7.1.2" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "solc": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", - "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } - }, - "solidity-coverage": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.5.11.tgz", - "integrity": "sha512-qikdsSi6+9XbfvwA0aI7HUVpF9fIFNqRWTw23M89GMDY+b6Gj0wWU9IngJS0fimoZIAdEp3bfChxvpfVcrUesg==", - "dev": true, - "requires": { - "death": "^1.1.0", - "ethereumjs-testrpc-sc": "6.1.6", - "istanbul": "^0.4.5", - "keccakjs": "^0.2.1", - "req-cwd": "^1.0.1", - "shelljs": "^0.7.4", - "sol-explore": "^1.6.2", - "solidity-parser-sc": "0.4.11", - "tree-kill": "^1.2.0", - "web3": "^0.18.4" - }, - "dependencies": { - "bignumber.js": { - "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "sol-explore": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/sol-explore/-/sol-explore-1.6.2.tgz", - "integrity": "sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI=", - "dev": true - }, - "web3": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", - "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", - "dev": true, - "requires": { - "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" - } - } - } - }, - "solidity-docgen": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.1.0.tgz", - "integrity": "sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g==", - "dev": true, - "requires": { - "commander": "^2.14.1", - "lodash": "^4.17.5", - "mocha": "^5.0.1", - "mustache": "^2.3.0", - "react": "^16.2.0", - "react-dom": "^16.2.0", - "shelljs": "^0.8.1" - }, - "dependencies": { - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - } - } - } - } - }, - "solidity-parser-sc": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/solidity-parser-sc/-/solidity-parser-sc-0.4.11.tgz", - "integrity": "sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw==", - "dev": true, - "requires": { - "mocha": "^4.1.0", - "pegjs": "^0.10.0", - "yargs": "^4.6.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "dev": true, - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } - }, - "solium": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/solium/-/solium-1.1.6.tgz", - "integrity": "sha512-hCZr5cEK2H6LVC1Lr7IGPGJ8Bs4Ktif9cmwnk3BHpoZLIwTtrNE0LUtTRBxkO3/G0GGB4OdxnnJT1pbgsJ/2Uw==", - "dev": true, - "requires": { - "ajv": "^5.2.2", - "chokidar": "^1.6.0", - "colors": "^1.1.2", - "commander": "^2.9.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.14.2", - "sol-digger": "0.0.2", - "sol-explore": "1.6.1", - "solium-plugin-security": "0.1.1", - "solparse": "2.2.4", - "text-table": "^0.2.0" - } - }, - "solium-plugin-security": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/solium-plugin-security/-/solium-plugin-security-0.1.1.tgz", - "integrity": "sha512-kpLirBwIq4mhxk0Y/nn5cQ6qdJTI+U1LO3gpoNIcqNaW+sI058moXBe2UiHs+9wvF9IzYD49jcKhFTxcR9u9SQ==", - "dev": true - }, - "solparse": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/solparse/-/solparse-2.2.4.tgz", - "integrity": "sha512-Sdyk983juUaOITdTD9U5Yc+MaX8kz4pN3wFyCRILWXW3+Ff96PxY9RLBuZINYbBgCAXN1a+kThJfFMlaXG9R6A==", - "dev": true, - "requires": { - "mocha": "^4.0.1", - "pegjs": "^0.10.0", - "yargs": "^10.0.3" - }, - "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "yargs": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", - "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" - } - }, - "yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "sorted-array-functions": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.2.0.tgz", - "integrity": "sha512-sWpjPhIZJtqO77GN+LD8dDsDKcWZ9GCOJNqKzi1tvtjGIzwfoyuRH8S0psunmc6Z5P+qfDqztSbwYR5X/e1UTg==", - "dev": true - }, - "source-list-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "requires": { - "source-map": "^0.5.6" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - }, - "stdio": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/stdio/-/stdio-0.2.7.tgz", - "integrity": "sha1-ocV9oQ/hz6oMO/aDydB0PRtmCDk=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-http": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", - "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-extended": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/string-extended/-/string-extended-0.0.8.tgz", - "integrity": "sha1-dBlX3/SHsCcqee7FpE8jnubxfM0=", - "dev": true, - "requires": { - "array-extended": "~0.0.5", - "date-extended": "~0.0.3", - "extended": "~0.0.3", - "is-extended": "~0.0.3" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "requires": { - "is-natural-number": "^4.0.1" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "swarm-js": { - "version": "0.1.37", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", - "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "decompress": "^4.0.0", - "eth-lib": "^0.1.26", - "fs-extra": "^2.1.2", - "fs-promise": "^2.0.0", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar.gz": "^1.0.5", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" - } - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "requires": { - "p-finally": "^1.0.0" - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "tape": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.0.tgz", - "integrity": "sha512-j0jO9BiScfqtPBb9QmPLL0qvxXMz98xjkMb7x8lKipFlJZwNJkqkWPou+NU4V6T9RnVh1kuSthLE8gLrN8bBfw==", - "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.2", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.1", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.5.0", - "resolve": "~1.5.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, - "tar-stream": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", - "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", - "requires": { - "bl": "^1.0.0", - "end-of-stream": "^1.0.0", - "readable-stream": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "tar.gz": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", - "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", - "requires": { - "bluebird": "^2.9.34", - "commander": "^2.8.1", - "fstream": "^1.0.8", - "mout": "^0.11.0", - "tar": "^2.1.1" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" - } - } - }, - "taskgroup": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/taskgroup/-/taskgroup-4.3.1.tgz", - "integrity": "sha1-feGT/r12gnPEV3MElwJNUSwnkVo=", - "dev": true, - "requires": { - "ambi": "^2.2.0", - "csextends": "^1.0.3" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timers-ext": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.3.tgz", - "integrity": "sha512-2iKErlS+NnEr0aQVQS91/mjsqCDO4OFl+5c5RDNtP+acQJTySvNSdbiSbmBD0t2RbErirF2Vq7x5YPQOSva77Q==", - "dev": true, - "requires": { - "es5-ext": "~0.10.14", - "next-tick": "1" - } - }, - "tingodb": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/tingodb/-/tingodb-0.6.1.tgz", - "integrity": "sha1-9jM2JZr336bJDf4lVqDfsNTu3lk=", - "dev": true, - "requires": { - "bson": "^1.0.4", - "lodash": "^4.17.5", - "safe": "^0.4.5", - "safe-buffer": "^5.1.1" - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - } - } - } - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "requires": { - "punycode": "^1.4.1" - } - }, - "tree-kill": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", - "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", - "dev": true - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, - "truffle": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.1.13.tgz", - "integrity": "sha1-vydYaYi0/4RWPt+/MrR5QUCKdq0=", - "dev": true, - "requires": { - "mocha": "^4.1.0", - "original-require": "1.0.1", - "solc": "0.4.24" - } - }, - "truffle-blockchain-utils": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.4.tgz", - "integrity": "sha512-wgRrhwqh0aea08Hz28hUV4tuF2uTVQH/e9kBou+WK04cqrutB5cxQVQ6HGjeZLltxBYOFvhrGOOq4l3WJFnPEA==" - }, - "truffle-contract": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/truffle-contract/-/truffle-contract-3.0.4.tgz", - "integrity": "sha512-/1LCtJFf5Jvm5Rv88T0d/rZSKvaiW/yO1SHXLGJgKzLsiG1F/2spFs4HrI1mRxP00opfrYXloEmLtkVV/kcndQ==", - "requires": { - "ethjs-abi": "0.1.8", - "truffle-blockchain-utils": "^0.0.4", - "truffle-contract-schema": "^2.0.0", - "truffle-error": "0.0.2", - "web3": "^0.20.1" - }, - "dependencies": { - "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" - }, - "ethjs-abi": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/ethjs-abi/-/ethjs-abi-0.1.8.tgz", - "integrity": "sha1-zSiFg+1ijN+tr4re+juh28vKbBg=", - "requires": { - "bn.js": "4.11.6", - "js-sha3": "0.5.5", - "number-to-bn": "1.7.0" - } - }, - "web3": { - "version": "0.20.6", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.6.tgz", - "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", - "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" - } - } - } - }, - "truffle-contract-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/truffle-contract-schema/-/truffle-contract-schema-2.0.0.tgz", - "integrity": "sha512-nLlspmu1GKDaluWksBwitHi/7Z3IpRjmBYeO9N+T1nVJD2V4IWJaptCKP1NqnPiJA+FChB7+F7pI6Br51/FtXQ==", - "requires": { - "ajv": "^5.1.1", - "crypto-js": "^3.1.9-1", - "debug": "^3.1.0" - }, - "dependencies": { - "crypto-js": { - "version": "3.1.9-1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", - "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "truffle-error": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/truffle-error/-/truffle-error-0.0.2.tgz", - "integrity": "sha1-AbGJt4UFVmrhaJwjnHyi3RIc/kw=" - }, - "truffle-hdwallet-provider-privkey": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.1.0.tgz", - "integrity": "sha512-Vj04yr2d9qLRZspoHztbE/YQnVaoFb90JNZHtggRUm+JFm/NOiSJHLVI63+3mtUIuQ04EuKZ7Df8JQw0Ni7IeA==", - "requires": { - "ethereumjs-tx": "^1.3.3", - "ethereumjs-wallet": "^0.6.0", - "web3": "^0.20.5", - "web3-provider-engine": "^13.6.4" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "bignumber.js": { - "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" - }, - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "web3": { - "version": "0.20.6", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.6.tgz", - "integrity": "sha1-PpcwauAk+yThCj11yIQwJWIhUSA=", - "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" - } - }, - "web3-provider-engine": { - "version": "13.6.6", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.6.6.tgz", - "integrity": "sha512-M9eztIxwCR2U7+d42RXdu3fBjvG/kcv7Ra8z2PHs912aHhAkMtNfvzhC8dboC7yKmj230eVHwouSXKizmSqC7Q==", - "requires": { - "async": "^2.5.0", - "clone": "^2.0.0", - "eth-block-tracker": "^2.2.2", - "eth-sig-util": "^1.4.2", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.1", - "ethereumjs-vm": "^2.0.2", - "fetch-ponyfill": "^4.0.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.67.0", - "semaphore": "^1.0.3", - "solc": "^0.4.2", - "tape": "^4.4.0", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - } - } - } - }, - "truffle-wallet-provider": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/truffle-wallet-provider/-/truffle-wallet-provider-0.0.5.tgz", - "integrity": "sha1-21nOb6HFWHZgERN1CalN/KjRQI4=", - "dev": true, - "requires": { - "ethereumjs-wallet": "^0.6.0", - "web3": "^0.18.2", - "web3-provider-engine": "^8.4.0" - }, - "dependencies": { - "bignumber.js": { - "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "dev": true - }, - "web3": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", - "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", - "dev": true, - "requires": { - "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" - } - } - } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.18" - } - }, - "typechecker": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/typechecker/-/typechecker-2.1.0.tgz", - "integrity": "sha1-0cIJOlT/ihn1jP+HfuqlTyJC04M=", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "ua-parser-js": { - "version": "0.7.18", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz", - "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA==", - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "optional": true - }, - "uglifyjs-webpack-plugin": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", - "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", - "requires": { - "source-map": "^0.5.6", - "uglify-js": "^2.8.29", - "webpack-sources": "^1.0.1" - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "unbzip2-stream": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", - "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", - "requires": { - "buffer": "^3.0.1", - "through": "^2.3.6" - }, - "dependencies": { - "base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=" - }, - "buffer": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", - "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", - "requires": { - "base64-js": "0.0.8", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - } - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "universalify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", - "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", - "dev": true - }, - "unorm": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", - "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - } - } - }, - "upath": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.5.tgz", - "integrity": "sha512-qbKn90aDQ0YEwvXoLqj0oiuUYroLX2lVHZ+b+xwjozFasAOC4GneDq5+OaIG5Zj+jFmbz/uO+f7a9qxjktJQww==" - }, - "uri-js": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", - "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", - "requires": { - "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" - } - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" - }, - "use": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", - "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", - "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - } - } - }, - "utf8": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", - "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=" - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" - }, - "valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", - "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "varint": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", - "integrity": "sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8=", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "requires": { - "indexof": "0.0.1" - } - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", - "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.1.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "watchr": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/watchr/-/watchr-2.4.13.tgz", - "integrity": "sha1-10hHu01vkPYf4sdPn2hmKqDgdgE=", - "dev": true, - "requires": { - "eachr": "^2.0.2", - "extendr": "^2.1.0", - "extract-opts": "^2.2.0", - "ignorefs": "^1.0.0", - "safefs": "^3.1.2", - "scandirectory": "^2.5.0", - "taskgroup": "^4.2.0", - "typechecker": "^2.0.8" - } - }, - "web3": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.33.tgz", - "integrity": "sha1-xgIbV2mSdyY3HBhLhoRFMRsTkpU=", - "requires": { - "web3-bzz": "1.0.0-beta.33", - "web3-core": "1.0.0-beta.33", - "web3-eth": "1.0.0-beta.33", - "web3-eth-personal": "1.0.0-beta.33", - "web3-net": "1.0.0-beta.33", - "web3-shh": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - } - }, - "web3-bzz": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.33.tgz", - "integrity": "sha1-MVAPaZt+cO31FJDFXv+0J7+7OwE=", - "requires": { - "got": "7.1.0", - "swarm-js": "0.1.37", - "underscore": "1.8.3" - }, - "dependencies": { - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "requires": { - "p-finally": "^1.0.0" - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "web3-core": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.33.tgz", - "integrity": "sha1-+C7VJfW2auzale7O08rSvWlfeDk=", - "requires": { - "web3-core-helpers": "1.0.0-beta.33", - "web3-core-method": "1.0.0-beta.33", - "web3-core-requestmanager": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - } - }, - "web3-core-helpers": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.33.tgz", - "integrity": "sha1-Kvcz5QTbBefDZIwdrPV3sOwV3EM=", - "requires": { - "underscore": "1.8.3", - "web3-eth-iban": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-core-method": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.33.tgz", - "integrity": "sha1-7Y7ExK+rIdwJid41g2hEZlIrboY=", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.33", - "web3-core-promievent": "1.0.0-beta.33", - "web3-core-subscriptions": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-core-promievent": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.33.tgz", - "integrity": "sha1-0fXrtgFSfdSWViw2IXblWNly01g=", - "requires": { - "any-promise": "1.3.0", - "eventemitter3": "1.1.1" - } - }, - "web3-core-requestmanager": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.33.tgz", - "integrity": "sha1-ejbEA1QALfsXnKLb22pgEsn3Ges=", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.33", - "web3-providers-http": "1.0.0-beta.33", - "web3-providers-ipc": "1.0.0-beta.33", - "web3-providers-ws": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-core-subscriptions": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.33.tgz", - "integrity": "sha1-YCh1yfTV9NDhYhRitfwewZs1veM=", - "requires": { - "eventemitter3": "1.1.1", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-eth": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.33.tgz", - "integrity": "sha1-hKn5TallUnyS2DitTlcN8CWJhJ8=", - "requires": { - "underscore": "1.8.3", - "web3-core": "1.0.0-beta.33", - "web3-core-helpers": "1.0.0-beta.33", - "web3-core-method": "1.0.0-beta.33", - "web3-core-subscriptions": "1.0.0-beta.33", - "web3-eth-abi": "1.0.0-beta.33", - "web3-eth-accounts": "1.0.0-beta.33", - "web3-eth-contract": "1.0.0-beta.33", - "web3-eth-iban": "1.0.0-beta.33", - "web3-eth-personal": "1.0.0-beta.33", - "web3-net": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-eth-abi": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.33.tgz", - "integrity": "sha1-IiH3FRZDZgAypN80D2EjSRaMgko=", - "requires": { - "bn.js": "4.11.6", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-eth-accounts": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.33.tgz", - "integrity": "sha1-JajX9OWOHpk7kvBpVILMzckhL5E=", - "requires": { - "any-promise": "1.3.0", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.7", - "scrypt.js": "0.2.0", - "underscore": "1.8.3", - "uuid": "2.0.1", - "web3-core": "1.0.0-beta.33", - "web3-core-helpers": "1.0.0-beta.33", - "web3-core-method": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", - "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" - } - } - }, - "web3-eth-contract": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.33.tgz", - "integrity": "sha1-nlkZ8pF6PGe0+2Vp1JxeMDiSW84=", - "requires": { - "underscore": "1.8.3", - "web3-core": "1.0.0-beta.33", - "web3-core-helpers": "1.0.0-beta.33", - "web3-core-method": "1.0.0-beta.33", - "web3-core-promievent": "1.0.0-beta.33", - "web3-core-subscriptions": "1.0.0-beta.33", - "web3-eth-abi": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-eth-iban": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.33.tgz", - "integrity": "sha1-HXPQxSiKRWWxdUp1tfs+oLd6Uy8=", - "requires": { - "bn.js": "4.11.6", - "web3-utils": "1.0.0-beta.33" - } - }, - "web3-eth-personal": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.33.tgz", - "integrity": "sha1-tOSFh8xOfrAY2ib947Tzul+bmO8=", - "requires": { - "web3-core": "1.0.0-beta.33", - "web3-core-helpers": "1.0.0-beta.33", - "web3-core-method": "1.0.0-beta.33", - "web3-net": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - } - }, - "web3-net": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.33.tgz", - "integrity": "sha1-tskNGg4WJuquiz2SKsFTZy/VZEU=", - "requires": { - "web3-core": "1.0.0-beta.33", - "web3-core-method": "1.0.0-beta.33", - "web3-utils": "1.0.0-beta.33" - } - }, - "web3-provider-engine": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-8.6.1.tgz", - "integrity": "sha1-TYbhnjDKr5ffNRUR7A9gE25bMOs=", - "dev": true, - "requires": { - "async": "^2.1.2", - "clone": "^2.0.0", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "^2.0.2", - "isomorphic-fetch": "^2.2.0", - "request": "^2.67.0", - "semaphore": "^1.0.3", - "solc": "^0.4.2", - "tape": "^4.4.0", - "web3": "^0.16.0", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, - "requires": { - "lodash": "^4.14.0" - } - }, - "bignumber.js": { - "version": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "from": "bignumber.js@git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "dev": true - }, - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - }, - "ethereumjs-util": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz", - "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==", - "dev": true, - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.3", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "web3": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.16.0.tgz", - "integrity": "sha1-pFVBdc1GKUMDWx8dOUMvdBxrYBk=", - "dev": true, - "requires": { - "bignumber.js": "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xmlhttprequest": "*" - } - } - } - }, - "web3-providers-http": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.33.tgz", - "integrity": "sha1-OzWuAO599blrSTSWKtSobypVmcE=", - "requires": { - "web3-core-helpers": "1.0.0-beta.33", - "xhr2": "0.1.4" - } - }, - "web3-providers-ipc": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.33.tgz", - "integrity": "sha1-Twrcmv6dEsBm5L5cPFNvUHPLB8Y=", - "requires": { - "oboe": "2.1.3", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.33" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-providers-ws": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.33.tgz", - "integrity": "sha1-j93qQuGbvyUh7IeVRkV6Yjqdye8=", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.33", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "web3-shh": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.33.tgz", - "integrity": "sha1-+Z4mVz9uCZMhrw2fK/z+Pe01UKE=", - "requires": { - "web3-core": "1.0.0-beta.33", - "web3-core-method": "1.0.0-beta.33", - "web3-core-subscriptions": "1.0.0-beta.33", - "web3-net": "1.0.0-beta.33" - } - }, - "web3-utils": { - "version": "1.0.0-beta.33", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.33.tgz", - "integrity": "sha1-4JG3mU8JtxSwGYpAV9OtLrjL4jg=", - "requires": { - "bn.js": "4.11.6", - "eth-lib": "0.1.27", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randomhex": "0.1.5", - "underscore": "1.8.3", - "utf8": "2.1.1" - }, - "dependencies": { - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - } - } - }, - "webpack": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz", - "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", - "requires": { - "acorn": "^5.0.0", - "acorn-dynamic-import": "^2.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "async": "^2.1.2", - "enhanced-resolve": "^3.4.0", - "escope": "^3.6.0", - "interpret": "^1.0.0", - "json-loader": "^0.5.4", - "json5": "^0.5.1", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "mkdirp": "~0.5.0", - "node-libs-browser": "^2.0.0", - "source-map": "^0.5.3", - "supports-color": "^4.2.1", - "tapable": "^0.2.7", - "uglifyjs-webpack-plugin": "^0.4.6", - "watchpack": "^1.4.0", - "webpack-sources": "^1.0.1", - "yargs": "^8.0.2" - }, - "dependencies": { - "ajv": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", - "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0", - "uri-js": "^4.2.1" - } - }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" - }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "enhanced-resolve": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", - "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "object-assign": "^4.0.1", - "tapable": "^0.2.7" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "requires": { - "has-flag": "^2.0.0" - } - }, - "tapable": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", - "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=" - }, - "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "webpack-sources": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "websocket": { - "version": "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", - "from": "websocket@git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c", - "requires": { - "debug": "^2.2.0", - "nan": "^2.3.3", - "typedarray-to-buffer": "^3.1.2", - "yaeti": "^0.0.6" - } - }, - "whatwg-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", - "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" - }, - "winston": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.3.tgz", - "integrity": "sha512-GYKuysPz2pxYAVJD2NPsDLP5Z79SDEzPm9/j4tCjkF/n89iBNGBMJcR+dMUqxgPNgoSs6fVygPi+Vl2oxIpBuw==", - "dev": true, - "requires": { - "async": "~1.0.0", - "colors": "1.0.x", - "cycle": "1.0.x", - "eyes": "0.1.x", - "isstream": "0.1.x", - "stack-trace": "0.0.x" - }, - "dependencies": { - "async": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", - "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=", - "dev": true - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - } - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "xhr": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.1.tgz", - "integrity": "sha512-pAIU5vBr9Hiy5cpFIbPnwf0C18ZF86DBsZKrlsf87N5De/JbA6RJ83UP/cv+aljl4S40iRVMqP4pr4sF9Dnj0A==", - "requires": { - "global": "~4.3.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", - "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", - "requires": { - "xhr-request": "^1.0.1" - } - }, - "xhr2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", - "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=" - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", - "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - } - }, - "yargs-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - }, - "yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.0.1" - } - } - } -} diff --git a/package.json b/package.json index 09e428066..f0d2f5ceb 100644 --- a/package.json +++ b/package.json @@ -63,14 +63,14 @@ "ethers": "^3.0.15", "fs": "0.0.1-security", "openzeppelin-solidity": "1.10.0", - "prettier": "^1.14.3", "readline-sync": "^1.4.9", + "request": "^2.88.0", "request-promise": "^4.2.2", "shelljs": "^0.8.2", "solc": "^0.4.24", "truffle-contract": "^3.0.4", "truffle-hdwallet-provider-privkey": "^0.1.0", - "web3": "^1.0.0-beta.33" + "web3": "1.0.0-beta.34" }, "devDependencies": { "@soldoc/soldoc": "^0.4.3", @@ -84,6 +84,7 @@ "ethereumjs-abi": "^0.6.5", "fast-csv": "^2.4.1", "ganache-cli": "^6.1.8", + "prettier": "^1.14.3", "sol-merger": "^0.1.2", "solidity-coverage": "^0.5.11", "solidity-docgen": "^0.1.0", diff --git a/yarn.lock b/yarn.lock index d9b04bce4..27308427c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,10 +5,12 @@ "@soldoc/markdown@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@soldoc/markdown/-/markdown-0.1.0.tgz#9f85be75049af9721b5129f133d52dafbf5f671e" + integrity sha512-V0UnvVVJ1qDzpuKLMuh7oHG94puwi8BI3t99Vrr7dQgIHuJdfZJ4SbGuWuFV/fSthyH++WY4ePO3d6gxfZ2//w== "@soldoc/soldoc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@soldoc/soldoc/-/soldoc-0.4.3.tgz#24ffee9264228e1c3edd61fd3162d63587954933" + integrity sha1-JP/ukmQijhw+3WH9MWLWNYeVSTM= dependencies: "@soldoc/markdown" "^0.1.0" chalk "^2.3.1" @@ -22,26 +24,31 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= abstract-leveldown@~2.6.0: version "2.6.3" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" + integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== dependencies: xtend "~4.0.0" abstract-leveldown@~2.7.1: version "2.7.2" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" + integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== dependencies: xtend "~4.0.0" accepts@~1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= dependencies: mime-types "~2.1.18" negotiator "0.6.1" @@ -49,46 +56,56 @@ accepts@~1.3.5: acorn-dynamic-import@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + integrity sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ= dependencies: acorn "^4.0.3" acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= dependencies: acorn "^3.0.4" acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= acorn@^5.0.0, acorn@^5.5.0: - version "5.5.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" + integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= -aes-js@^0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d" +aes-js@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" + integrity sha512-cEA0gBelItZZV7iBiL8ApCiNgc+gBWJJ4uoORhbu6vOqAJ0UL9wIlxr4RI7ij9SSVzy6AnPwiu37kVYiHCl3nw== ajv-keywords@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I= ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= -ajv@^5.1.0, ajv@^5.1.1, ajv@^5.2.2, ajv@^5.2.3, ajv@^5.3.0: +ajv@^5.1.1, ajv@^5.2.2, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -96,17 +113,19 @@ ajv@^5.1.0, ajv@^5.1.1, ajv@^5.2.2, ajv@^5.2.3, ajv@^5.3.0: json-schema-traverse "^0.3.0" ajv@^6.1.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.0.tgz#4c8affdf80887d8f132c9c52ab8a2dc4d0b7b24c" + version "6.5.4" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.4.tgz#247d5274110db653706b550fcc2b797ca28cfc59" + integrity sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - uri-js "^4.2.1" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= dependencies: kind-of "^3.0.2" longest "^1.0.1" @@ -115,6 +134,7 @@ align-text@^0.1.1, align-text@^0.1.3: ambi@^2.2.0: version "2.5.0" resolved "https://registry.yarnpkg.com/ambi/-/ambi-2.5.0.tgz#7c8e372be48891157e7cea01cb6f9143d1f74220" + integrity sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA= dependencies: editions "^1.1.1" typechecker "^4.3.0" @@ -122,36 +142,44 @@ ambi@^2.2.0: amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" any-promise@1.3.0, any-promise@^1.0.0, any-promise@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= anymatch@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== dependencies: micromatch "^2.1.5" normalize-path "^2.0.0" @@ -159,6 +187,7 @@ anymatch@^1.3.0: anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== dependencies: micromatch "^3.1.4" normalize-path "^2.1.1" @@ -166,10 +195,12 @@ anymatch@^2.0.0: aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" readable-stream "^2.0.6" @@ -177,12 +208,14 @@ are-we-there-yet@~1.1.2: argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" arguments-extended@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/arguments-extended/-/arguments-extended-0.0.3.tgz#6107e4917d0eb6f0a4dd66320fc15afc72ef4946" + integrity sha1-YQfkkX0OtvCk3WYyD8Fa/HLvSUY= dependencies: extended "~0.0.3" is-extended "~0.0.8" @@ -190,24 +223,29 @@ arguments-extended@~0.0.3: arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= dependencies: arr-flatten "^1.0.1" arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-extended@~0.0.3, array-extended@~0.0.4, array-extended@~0.0.5: version "0.0.11" resolved "https://registry.yarnpkg.com/array-extended/-/array-extended-0.0.11.tgz#d7144ae748de93ca726f121009dbff1626d164bd" + integrity sha1-1xRK50jek8pybxIQCdv/FibRZL0= dependencies: arguments-extended "~0.0.3" extended "~0.0.3" @@ -216,66 +254,77 @@ array-extended@~0.0.3, array-extended@~0.0.4, array-extended@~0.0.5: array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= dependencies: array-uniq "^1.0.1" array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== dependencies: bn.js "^4.0.0" inherits "^2.0.1" minimalistic-assert "^1.0.0" asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= assert@^1.1.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= dependencies: util "0.10.3" assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + integrity sha1-GdOGodntxufByF04iu28xW0zYC0= async-eventemitter@^0.2.2: version "0.2.4" resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== dependencies: async "^2.4.0" @@ -288,58 +337,58 @@ async-eventemitter@ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== -async@1.x, async@^1.4.0, async@^1.4.2, async@~1.5.2: +async@1.x, async@^1.4.2, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= -async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" - dependencies: - lodash "^4.14.0" - -async@^2.4.1: +async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.4.1, async@^2.5.0: version "2.6.1" resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== dependencies: lodash "^4.17.10" async@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k= asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= atob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.6.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= dependencies: chalk "^1.1.3" esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@^6.0.14: +babel-core@^6.0.14, babel-core@^6.26.0: version "6.26.3" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== dependencies: babel-code-frame "^6.26.0" babel-generator "^6.26.0" @@ -361,33 +410,10 @@ babel-core@^6.0.14: slash "^1.0.0" source-map "^0.5.7" -babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - babel-generator@^6.26.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== dependencies: babel-messages "^6.23.0" babel-runtime "^6.26.0" @@ -401,6 +427,7 @@ babel-generator@^6.26.0: babel-helper-bindify-decorators@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + integrity sha1-FMGeXxQte0fxmlJDHlKxzLxAozA= dependencies: babel-runtime "^6.22.0" babel-traverse "^6.24.1" @@ -409,6 +436,7 @@ babel-helper-bindify-decorators@^6.24.1: babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= dependencies: babel-helper-explode-assignable-expression "^6.24.1" babel-runtime "^6.22.0" @@ -417,6 +445,7 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= dependencies: babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" @@ -426,6 +455,7 @@ babel-helper-call-delegate@^6.24.1: babel-helper-define-map@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.26.0" @@ -435,6 +465,7 @@ babel-helper-define-map@^6.24.1: babel-helper-explode-assignable-expression@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= dependencies: babel-runtime "^6.22.0" babel-traverse "^6.24.1" @@ -443,6 +474,7 @@ babel-helper-explode-assignable-expression@^6.24.1: babel-helper-explode-class@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= dependencies: babel-helper-bindify-decorators "^6.24.1" babel-runtime "^6.22.0" @@ -452,6 +484,7 @@ babel-helper-explode-class@^6.24.1: babel-helper-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= dependencies: babel-helper-get-function-arity "^6.24.1" babel-runtime "^6.22.0" @@ -462,6 +495,7 @@ babel-helper-function-name@^6.24.1: babel-helper-get-function-arity@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -469,6 +503,7 @@ babel-helper-get-function-arity@^6.24.1: babel-helper-hoist-variables@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -476,6 +511,7 @@ babel-helper-hoist-variables@^6.24.1: babel-helper-optimise-call-expression@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -483,6 +519,7 @@ babel-helper-optimise-call-expression@^6.24.1: babel-helper-regex@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= dependencies: babel-runtime "^6.26.0" babel-types "^6.26.0" @@ -491,6 +528,7 @@ babel-helper-regex@^6.24.1: babel-helper-remap-async-to-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" @@ -501,6 +539,7 @@ babel-helper-remap-async-to-generator@^6.24.1: babel-helper-replace-supers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= dependencies: babel-helper-optimise-call-expression "^6.24.1" babel-messages "^6.23.0" @@ -512,6 +551,7 @@ babel-helper-replace-supers@^6.24.1: babel-helpers@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" @@ -519,50 +559,61 @@ babel-helpers@^6.24.1: babel-messages@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= dependencies: babel-runtime "^6.22.0" babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= dependencies: babel-runtime "^6.22.0" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= babel-plugin-syntax-async-generators@^6.5.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + integrity sha1-a8lj67FuzLrmuStZbrfzXDQqi5o= babel-plugin-syntax-class-properties@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= babel-plugin-syntax-decorators@^6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= babel-plugin-transform-async-generator-functions@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= dependencies: babel-helper-remap-async-to-generator "^6.24.1" babel-plugin-syntax-async-generators "^6.5.0" @@ -571,6 +622,7 @@ babel-plugin-transform-async-generator-functions@^6.24.1: babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= dependencies: babel-helper-remap-async-to-generator "^6.24.1" babel-plugin-syntax-async-functions "^6.8.0" @@ -579,6 +631,7 @@ babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async- babel-plugin-transform-class-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= dependencies: babel-helper-function-name "^6.24.1" babel-plugin-syntax-class-properties "^6.8.0" @@ -588,6 +641,7 @@ babel-plugin-transform-class-properties@^6.24.1: babel-plugin-transform-decorators@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + integrity sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0= dependencies: babel-helper-explode-class "^6.24.1" babel-plugin-syntax-decorators "^6.13.0" @@ -598,18 +652,21 @@ babel-plugin-transform-decorators@^6.24.1: babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= dependencies: babel-runtime "^6.26.0" babel-template "^6.26.0" @@ -620,6 +677,7 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es20 babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= dependencies: babel-helper-define-map "^6.24.1" babel-helper-function-name "^6.24.1" @@ -634,6 +692,7 @@ babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-cla babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= dependencies: babel-runtime "^6.22.0" babel-template "^6.24.1" @@ -641,12 +700,14 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transfor babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2015-duplicate-keys@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -654,12 +715,14 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2 babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= dependencies: babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" @@ -668,29 +731,23 @@ babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es20 babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= dependencies: babel-plugin-transform-es2015-modules-commonjs "^6.24.1" babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-commonjs@^6.23.0: +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== dependencies: babel-plugin-transform-strict-mode "^6.24.1" babel-runtime "^6.26.0" @@ -700,6 +757,7 @@ babel-plugin-transform-es2015-modules-commonjs@^6.24.1: babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= dependencies: babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" @@ -708,6 +766,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-e babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015-modules-umd@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= dependencies: babel-plugin-transform-es2015-modules-amd "^6.24.1" babel-runtime "^6.22.0" @@ -716,6 +775,7 @@ babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015 babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= dependencies: babel-helper-replace-supers "^6.24.1" babel-runtime "^6.22.0" @@ -723,6 +783,7 @@ babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es201 babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-parameters@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= dependencies: babel-helper-call-delegate "^6.24.1" babel-helper-get-function-arity "^6.24.1" @@ -734,6 +795,7 @@ babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015- babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -741,12 +803,14 @@ babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transfo babel-plugin-transform-es2015-spread@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= dependencies: babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" @@ -755,18 +819,21 @@ babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es201 babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es2015-unicode-regex@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= dependencies: babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" @@ -775,6 +842,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es20 babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= dependencies: babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" babel-plugin-syntax-exponentiation-operator "^6.8.0" @@ -783,6 +851,7 @@ babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-e babel-plugin-transform-object-rest-spread@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= dependencies: babel-plugin-syntax-object-rest-spread "^6.8.0" babel-runtime "^6.26.0" @@ -790,12 +859,14 @@ babel-plugin-transform-object-rest-spread@^6.22.0: babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= dependencies: regenerator-transform "^0.10.0" babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= dependencies: babel-runtime "^6.22.0" babel-types "^6.24.1" @@ -803,14 +874,16 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-polyfill@6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= dependencies: babel-runtime "^6.26.0" core-js "^2.5.0" regenerator-runtime "^0.10.5" -babel-preset-env@^1.3.2: +babel-preset-env@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== dependencies: babel-plugin-check-es2015-constants "^6.22.0" babel-plugin-syntax-trailing-function-commas "^6.22.0" @@ -846,6 +919,7 @@ babel-preset-env@^1.3.2: babel-preset-es2015@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + integrity sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk= dependencies: babel-plugin-check-es2015-constants "^6.22.0" babel-plugin-transform-es2015-arrow-functions "^6.22.0" @@ -875,6 +949,7 @@ babel-preset-es2015@6.24.1: babel-preset-stage-2@6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + integrity sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE= dependencies: babel-plugin-syntax-dynamic-import "^6.18.0" babel-plugin-transform-class-properties "^6.24.1" @@ -884,6 +959,7 @@ babel-preset-stage-2@6.24.1: babel-preset-stage-3@6.24.1, babel-preset-stage-3@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + integrity sha1-g2raCp56f6N8sTj7kyb4eTSkg5U= dependencies: babel-plugin-syntax-trailing-function-commas "^6.22.0" babel-plugin-transform-async-generator-functions "^6.24.1" @@ -894,6 +970,7 @@ babel-preset-stage-3@6.24.1, babel-preset-stage-3@^6.24.1: babel-register@6.26.0, babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= dependencies: babel-core "^6.26.0" babel-runtime "^6.26.0" @@ -906,6 +983,7 @@ babel-register@6.26.0, babel-register@^6.26.0: babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" @@ -913,6 +991,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: babel-template@^6.24.1, babel-template@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= dependencies: babel-runtime "^6.26.0" babel-traverse "^6.26.0" @@ -923,6 +1002,7 @@ babel-template@^6.24.1, babel-template@^6.26.0: babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= dependencies: babel-code-frame "^6.26.0" babel-messages "^6.23.0" @@ -937,6 +1017,7 @@ babel-traverse@^6.24.1, babel-traverse@^6.26.0: babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= dependencies: babel-runtime "^6.26.0" esutils "^2.0.2" @@ -946,6 +1027,7 @@ babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: babelify@^7.3.0: version "7.3.0" resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" + integrity sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU= dependencies: babel-core "^6.0.14" object-assign "^4.0.0" @@ -953,32 +1035,34 @@ babelify@^7.3.0: babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -base-x@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-1.1.0.tgz#42d3d717474f9ea02207f6d1aa1f426913eeb7ac" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base-x@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.4.tgz#94c1788736da065edb1d68808869e357c977fa77" + integrity sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA== dependencies: safe-buffer "^5.0.1" base64-js@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" + integrity sha1-EQHpVE9KdrG8OybUUsqW16NeeXg= base64-js@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" class-utils "^0.3.5" @@ -989,26 +1073,31 @@ base@^0.11.1: pascalcase "^0.1.1" bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= dependencies: tweetnacl "^0.14.3" big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== bignumber.js@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" + integrity sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA== bignumber.js@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-5.0.0.tgz#fbce63f09776b3000a83185badcde525daf34833" + integrity sha512-KWTu6ZMVk9sxlDJQh2YH1UOnfDP8O8TpxUxgQG/vKASoSnEjK9aVuOueFaPcQEYQ5fyNXNTOYwYw3099RYebWg== bignumber.js@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-6.0.0.tgz#bbfa047644609a5af093e9cbd83b0461fa3f6002" + integrity sha512-x247jIuy60/+FtMRvscqfxtVHQf8AGx2hm9c6btkgC0x/hp9yt+teISNhvF8WlwRkCc5yF2fDECH8SIMe8j+GA== "bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" @@ -1023,22 +1112,26 @@ bignumber.js@^6.0.0: resolved "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== bindings@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" + integrity sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw== bip66@^1.1.3: version "1.1.5" resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= dependencies: safe-buffer "^5.0.1" bitcore-lib@^0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/bitcore-lib/-/bitcore-lib-0.15.0.tgz#f924be13869f2aab7e04aeec5642ad3359b6cec2" + integrity sha512-AeXLWhiivF6CDFzrABZHT4jJrflyylDWTi32o30rF92HW9msfuKpjzrHtFKYGa9w0kNVv5HABQjCB3OEav4PhQ== dependencies: bn.js "=4.11.8" bs58 "=4.0.1" @@ -1050,6 +1143,7 @@ bitcore-lib@^0.15.0: bitcore-mnemonic@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bitcore-mnemonic/-/bitcore-mnemonic-1.5.0.tgz#c7e785beb6bf0616ed4992785dc3658670425a39" + integrity sha512-sbeP4xwkindLMfIQhVxj6rZSDMwtiKmfc1DqvwpR6Yg+Qo4I4WHO5pvzb12Y04uDh1N3zgD45esHhfH0HHmE4g== dependencies: bitcore-lib "^0.15.0" unorm "^1.3.3" @@ -1057,6 +1151,7 @@ bitcore-mnemonic@^1.5.0: bl@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== dependencies: readable-stream "^2.3.5" safe-buffer "^5.1.1" @@ -1064,59 +1159,55 @@ bl@^1.0.0: block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= dependencies: inherits "~2.0.0" bluebird@^2.9.34: version "2.11.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE= bluebird@^3.4.6, bluebird@^3.5.0: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + version "3.5.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" + integrity sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg== bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= bn.js@=4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.6, bn.js@^4.4.0, bn.js@^4.8.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== bn.js@^2.0.3: version "2.2.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.2.0.tgz#12162bc2ae71fc40a5626c33438f3a875cd37625" + integrity sha1-EhYrwq5x/EClYmwzQ486h1zTdiU= -body-parser@1.18.2, body-parser@^1.16.0: - version "1.18.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" +body-parser@1.18.3, body-parser@^1.16.0: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= dependencies: bytes "3.0.0" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.1" - http-errors "~1.6.2" - iconv-lite "0.4.19" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" on-finished "~2.3.0" - qs "6.5.1" - raw-body "2.3.2" - type-is "~1.6.15" - -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" borc@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/borc/-/borc-2.0.3.tgz#08845ea73a6d3211120928ee3929f8dc2de9f52e" + integrity sha512-2mfipKUXn7yLgwn8D5jZkJqd2ZyzqmYZQX/9d4On33oGNDLwxj5qQMst+nkKyEdaujQRFfrZCId+k8wehQVANg== dependencies: bignumber.js "^6.0.0" commander "^2.15.0" @@ -1126,6 +1217,7 @@ borc@^2.0.2: brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1133,6 +1225,7 @@ brace-expansion@^1.1.7: braces@^1.8.2: version "1.8.5" resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= dependencies: expand-range "^1.8.1" preserve "^0.2.0" @@ -1141,6 +1234,7 @@ braces@^1.8.2: braces@^2.3.0, braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" @@ -1156,18 +1250,22 @@ braces@^2.3.0, braces@^2.3.1: brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= browser-stdout@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" cipher-base "^1.0.0" @@ -1179,22 +1277,26 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: browserify-cipher@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" browserify-des "^1.0.0" evp_bytestokey "^1.0.0" browserify-des@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.1.tgz#3343124db6d7ad53e26a8826318712bdc8450f9c" + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" des.js "^1.0.0" inherits "^2.0.1" + safe-buffer "^5.1.2" browserify-rsa@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= dependencies: bn.js "^4.1.0" randombytes "^2.0.1" @@ -1202,12 +1304,14 @@ browserify-rsa@^4.0.0: browserify-sha3@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/browserify-sha3/-/browserify-sha3-0.0.1.tgz#3ff34a3006ef15c0fb3567e541b91a2340123d11" + integrity sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE= dependencies: js-sha3 "^0.3.1" browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= dependencies: bn.js "^4.1.1" browserify-rsa "^4.0.0" @@ -1220,81 +1324,91 @@ browserify-sign@^4.0.0: browserify-zlib@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== dependencies: pako "~1.0.5" browserslist@^3.2.6: - version "3.2.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.7.tgz#aa488634d320b55e88bab0256184dbbcca1e6de9" + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== dependencies: - caniuse-lite "^1.0.30000835" - electron-to-chromium "^1.3.45" + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" -bs58@=4.0.1, bs58@^4.0.1: +bs58@=4.0.1, bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= dependencies: base-x "^3.0.2" bs58@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" + integrity sha1-VZCNWPGYKrogCPob7Y+RmYopv40= -bs58@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-3.1.0.tgz#d4c26388bf4804cac714141b1945aa47e5eb248e" - dependencies: - base-x "^1.1.0" - -bs58check@^1.0.8: - version "1.3.4" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-1.3.4.tgz#c52540073749117714fa042c3047eb8f9151cbf8" +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== dependencies: - bs58 "^3.1.0" + bs58 "^4.0.0" create-hash "^1.1.0" + safe-buffer "^5.1.2" bson@^1.0.4: version "1.1.0" resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.0.tgz#bee57d1fb6a87713471af4e32bcae36de814b5b0" + integrity sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA== -buffer-alloc-unsafe@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz#ffe1f67551dd055737de253337bfe853dfab1a6a" - -buffer-alloc@^1.1.0: +buffer-alloc-unsafe@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.1.0.tgz#05514d33bf1656d3540c684f65b1202e90eca303" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== dependencies: - buffer-alloc-unsafe "^0.1.0" - buffer-fill "^0.1.0" + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" buffer-compare@=1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-compare/-/buffer-compare-1.1.1.tgz#5be7be853af89198d1f4ddc090d1d66a48aef596" + integrity sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY= buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= -buffer-fill@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-0.1.1.tgz#76d825c4d6e50e06b7a31eb520c04d08cc235071" +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= buffer-from@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== buffer-to-arraybuffer@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha1-YGSkD6dutDxyOrqe+PbhIW0QURo= buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^3.0.1: version "3.6.0" resolved "https://registry.yarnpkg.com/buffer/-/buffer-3.6.0.tgz#a72c936f77b96bf52f5f7e7b467180628551defb" + integrity sha1-pyyTb3e5a/UvX357RnGAYoVR3vs= dependencies: base64-js "0.0.8" ieee754 "^1.1.4" @@ -1303,14 +1417,16 @@ buffer@^3.0.1: buffer@^4.3.0, buffer@^4.9.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" isarray "^1.0.0" buffer@^5.0.5: - version "5.1.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.1.0.tgz#c913e43678c7cb7c8bd16afbcddb6c5505e8f9fe" + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1318,18 +1434,22 @@ buffer@^5.0.5: builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" component-emitter "^1.2.1" @@ -1344,43 +1464,52 @@ cache-base@^1.0.1: caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= dependencies: callsites "^0.2.0" callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= caminte@0.3.7: version "0.3.7" resolved "https://registry.yarnpkg.com/caminte/-/caminte-0.3.7.tgz#ec1ec0457664a0f092643b7c646c457d5cd6f693" + integrity sha1-7B7ARXZkoPCSZDt8ZGxFfVzW9pM= dependencies: bluebird "^3.4.6" uuid "^3.0.1" -caniuse-lite@^1.0.30000835: - version "1.0.30000840" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000840.tgz#344513f8f843536cf99694964c09811277eee395" +caniuse-lite@^1.0.30000844: + version "1.0.30000890" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000890.tgz#86a18ffcc65d79ec6a437e985761b8bf1c4efeaf" + integrity sha512-4NI3s4Y6ROm+SgZN5sLUG4k7nVWQnedis3c/RWkynV5G6cHSY7+a8fwFyn2yoBDE3E6VswhTNNwR3PvzGqlTkg== caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= dependencies: align-text "^0.1.3" lazy-cache "^1.0.3" @@ -1388,6 +1517,7 @@ center-align@^0.1.1: chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1398,6 +1528,7 @@ chalk@^1.1.3: chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -1406,16 +1537,19 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1: chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= checkpoint-store@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" + integrity sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY= dependencies: functional-red-black-tree "^1.0.1" chokidar@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= dependencies: anymatch "^1.3.0" async-each "^1.0.0" @@ -1429,8 +1563,9 @@ chokidar@^1.6.0: fsevents "^1.0.0" chokidar@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176" + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== dependencies: anymatch "^2.0.0" async-each "^1.0.0" @@ -1439,20 +1574,23 @@ chokidar@^2.0.2: inherits "^2.0.1" is-binary-path "^1.0.0" is-glob "^4.0.0" + lodash.debounce "^4.0.8" normalize-path "^2.1.1" path-is-absolute "^1.0.0" readdirp "^2.0.0" - upath "^1.0.0" + upath "^1.0.5" optionalDependencies: - fsevents "^1.1.2" + fsevents "^1.2.2" chownr@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -1460,10 +1598,12 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" define-property "^0.2.5" @@ -1471,29 +1611,33 @@ class-utils@^0.3.5: static-extend "^0.1.1" cli-color@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-1.2.0.tgz#3a5ae74fd76b6267af666e69e2afbbd01def34d1" + version "1.3.0" + resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-1.3.0.tgz#cd2ec212efbd1a0eeb5b017f17d4e2d15e91420f" + integrity sha512-XmbLr8MzgOup/sPHF4nOZerCOcL7rD7vKWpEl0axUsMAY+AEimOhYva1ksskWqkLGY/bjR9h7Cfbr+RrJRfmTQ== dependencies: ansi-regex "^2.1.1" d "1" - es5-ext "^0.10.12" - es6-iterator "2" - memoizee "^0.4.3" - timers-ext "0.1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + memoizee "^0.4.14" + timers-ext "^0.1.5" cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= dependencies: restore-cursor "^2.0.0" cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= dependencies: center-align "^0.1.1" right-align "^0.1.1" @@ -1502,6 +1646,7 @@ cliui@^2.1.0: cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -1510,30 +1655,31 @@ cliui@^3.2.0: cliui@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== dependencies: string-width "^2.1.1" strip-ansi "^4.0.0" wrap-ansi "^2.0.0" -clone@2.x: +clone@2.x, clone@^2.0.0: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - -clone@^2.0.0, clone@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= coinstring@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/coinstring/-/coinstring-2.3.0.tgz#cdb63363a961502404a25afb82c2e26d5ff627a4" + integrity sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q= dependencies: bs58 "^2.0.1" create-hash "^1.1.1" @@ -1541,71 +1687,93 @@ coinstring@^2.0.0: collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" object-visit "^1.0.0" color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: - color-name "^1.1.1" + color-name "1.1.3" -color-name@^1.1.1: +color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= colors@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= colors@^1.1.2: - version "1.2.5" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc" + version "1.3.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" + integrity sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ== -combined-stream@1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: +combined-stream@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + integrity sha1-cj599ugBrFYTETp+RFqbactjKBg= + dependencies: + delayed-stream "~1.0.0" + +combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== dependencies: delayed-stream "~1.0.0" commander@2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== -commander@2.15.1, commander@^2.8.1, commander@^2.9.0: +commander@2.15.1: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== -commander@^2.11.0: - version "2.14.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" +commander@^2.11.0, commander@^2.14.1, commander@^2.15.0, commander@^2.8.1, commander@^2.9.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== -commander@^2.14.1, commander@^2.15.0: +commander@~2.17.1: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== commander@~2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= dependencies: graceful-readlink ">= 1.0.0" compare-versions@^3.0.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.0.tgz#af93ea705a96943f622ab309578b9b90586f39c3" + version "3.4.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" + integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== dependencies: buffer-from "^1.0.0" inherits "^2.0.3" @@ -1615,77 +1783,96 @@ concat-stream@^1.6.0: console-browserify@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= dependencies: date-now "^0.1.4" console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.5.0, convert-source-map@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" +convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookiejar@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js@^2.4.0, core-js@^2.5.0: - version "2.5.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cors@^2.8.1: version "2.8.4" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" + integrity sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY= dependencies: object-assign "^4" vary "^1" coveralls@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.1.tgz#12e15914eaa29204e56869a5ece7b9e1492d2ae2" + version "3.0.2" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.2.tgz#f5a0bcd90ca4e64e088b710fa8dda640aea4884f" + integrity sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw== dependencies: - js-yaml "^3.6.1" + growl "~> 1.10.0" + js-yaml "^3.11.0" lcov-parse "^0.0.10" - log-driver "^1.2.5" + log-driver "^1.2.7" minimist "^1.2.0" - request "^2.79.0" + request "^2.85.0" create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== dependencies: bn.js "^4.1.0" elliptic "^6.0.0" @@ -1693,6 +1880,7 @@ create-ecdh@^4.0.0: create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" inherits "^2.0.1" @@ -1703,6 +1891,7 @@ create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" create-hash "^1.1.0" @@ -1712,8 +1901,9 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: sha.js "^2.4.8" cron-parser@^2.4.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.5.0.tgz#ec1385a3aa8c63624256789ce2ecfa338384676a" + version "2.6.0" + resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.6.0.tgz#ae2514ceda9ccb540256e201bdd23ae814e03674" + integrity sha512-KGfDDTjBIx85MnVYcdhLccoJH/7jcYW+5Z/t3Wsg2QlJhmmjf+97z+9sQftS71lopOYYapjEKEvmWaCsym5Z4g== dependencies: is-nan "^1.2.1" moment-timezone "^0.5.0" @@ -1721,20 +1911,16 @@ cron-parser@^2.4.0: cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" which "^1.2.9" -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - crypto-browserify@3.12.0, crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" browserify-sign "^4.0.0" @@ -1751,38 +1937,46 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0: crypto-js@^3.1.4, crypto-js@^3.1.5: version "3.1.8" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.8.tgz#715f070bf6014f2ae992a98b3929258b713f08d5" + integrity sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU= crypto-js@^3.1.9-1: version "3.1.9-1" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8" + integrity sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg= crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= csextends@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/csextends/-/csextends-1.2.0.tgz#6374b210984b54d4495f29c99d3dd069b80543e5" + integrity sha512-S/8k1bDTJIwuGgQYmsRoE+8P+ohV32WhQ0l4zqrc0XDdxOhjQQD7/wTZwCzoZX53jSX3V/qwjT+OkPTxWQcmjg== cycle@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= dependencies: es5-ext "^0.10.9" dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= dependencies: assert-plus "^1.0.0" date-extended@~0.0.3: version "0.0.6" resolved "https://registry.yarnpkg.com/date-extended/-/date-extended-0.0.6.tgz#23802d57dd1bf7818813fe0c32e851a86da267c9" + integrity sha1-I4AtV90b94GIE/4MMuhRqG2iZ8k= dependencies: array-extended "~0.0.3" extended "~0.0.3" @@ -1791,44 +1985,67 @@ date-extended@~0.0.3: date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= death@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" + integrity sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg= -debug@*, debug@3.1.0, debug@^3.0.1, debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" +debug@*: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== dependencies: - ms "2.0.0" + ms "^2.1.1" debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" +debug@^3.0.1, debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + decamelize@^1.0.0, decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= declare.js@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/declare.js/-/declare.js-0.0.8.tgz#0478adff9564c004f51df73d8bc134019d28dcde" + integrity sha1-BHit/5VkwAT1Hfc9i8E0AZ0o3N4= decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= decompress-response@^3.2.0, decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= dependencies: mimic-response "^1.0.0" decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== dependencies: file-type "^5.2.0" is-stream "^1.1.0" @@ -1837,6 +2054,7 @@ decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: decompress-tarbz2@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== dependencies: decompress-tar "^4.1.0" file-type "^6.1.0" @@ -1847,6 +2065,7 @@ decompress-tarbz2@^4.0.0: decompress-targz@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== dependencies: decompress-tar "^4.1.1" file-type "^5.2.0" @@ -1855,6 +2074,7 @@ decompress-targz@^4.0.0: decompress-unzip@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= dependencies: file-type "^3.8.0" get-stream "^2.2.0" @@ -1864,6 +2084,7 @@ decompress-unzip@^4.0.1: decompress@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" + integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50= dependencies: decompress-tar "^4.0.0" decompress-tarbz2 "^4.0.0" @@ -1877,49 +2098,57 @@ decompress@^4.0.0: deep-assign@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-2.0.0.tgz#ebe06b1f07f08dae597620e3dd1622f371a1c572" + integrity sha1-6+BrHwfwja5ZdiDj3RYi83GhxXI= dependencies: is-obj "^1.0.0" deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= -deep-extend@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= deferred-leveldown@~1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" + integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== dependencies: abstract-leveldown "~2.6.0" define-properties@^1.1.1, define-properties@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: - foreach "^2.0.5" - object-keys "^1.0.8" + object-keys "^1.0.12" define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" @@ -1927,10 +2156,12 @@ define-property@^2.0.2: defined@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag= dependencies: globby "^5.0.0" is-path-cwd "^1.0.0" @@ -1943,26 +2174,27 @@ del@^2.0.2: delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= delimit-stream@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/delimit-stream/-/delimit-stream-0.1.0.tgz#9b8319477c0e5f8aeb3ce357ae305fc25ea1cd2b" + integrity sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs= -depd@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" - -depd@~1.1.1, depd@~1.1.2: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -1970,28 +2202,34 @@ des.js@^1.0.0: destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= dependencies: repeating "^2.0.0" detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= diff@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" + integrity sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww== diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" miller-rabin "^4.0.0" @@ -2000,6 +2238,7 @@ diffie-hellman@^5.0.0: doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= dependencies: esutils "^2.0.2" isarray "^1.0.0" @@ -2007,20 +2246,24 @@ doctrine@1.5.0: doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== dependencies: esutils "^2.0.2" dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== drbg.js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs= dependencies: browserify-aes "^1.0.6" create-hash "^1.1.2" @@ -2029,43 +2272,60 @@ drbg.js@^1.0.1: duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= eachr@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/eachr/-/eachr-2.0.4.tgz#466f7caa10708f610509e32c807aafe57fc122bf" + integrity sha1-Rm98qhBwj2EFCeMsgHqv5X/BIr8= dependencies: typechecker "^2.0.8" ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= dependencies: jsbn "~0.1.0" + safer-buffer "^2.1.0" editions@^1.1.1, editions@^1.3.3, editions@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" + integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg== + +editions@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/editions/-/editions-2.0.2.tgz#54fdac6fb24b0a1a72ffc1ba0126c10602c3e0bd" + integrity sha512-0B8aSTWUu9+JW99zHoeogavCi+lkE5l35FK0OKe0pCobixJYoeof3ZujtqYzSsU2MskhRadY5V9oWUuyG4aJ3A== + dependencies: + errlop "^1.0.2" + semver "^5.5.0" ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.45: - version "1.3.45" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.45.tgz#458ac1b1c5c760ce8811a16d2bfbd97ec30bafb8" +electron-to-chromium@^1.3.47: + version "1.3.78" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.78.tgz#ecb72b5b166ba6598efb384461d63cad74678ebf" + integrity sha512-p4D/5iX08c3LNep5bWn/X3dFmec1K9le6O43lgRsO/vYKBTH2smWDMDfkGlPtERFcLVkI8xdKW5EokBZODh1xg== elliptic@6.3.3: version "6.3.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" + integrity sha1-VILZZG1UvLif19mU/J4ulWiHbj8= dependencies: bn.js "^4.4.0" brorand "^1.0.1" hash.js "^1.0.0" inherits "^2.0.1" -elliptic@=6.4.0, elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: +elliptic@=6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + integrity sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8= dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2078,56 +2338,90 @@ elliptic@=6.4.0, elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: elliptic@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-3.1.0.tgz#c21682ef762769b56a74201609105da11d5f60cc" + integrity sha1-whaC73YnabVqdCAWCRBdoR1fYMw= dependencies: bn.js "^2.0.3" brorand "^1.0.1" hash.js "^1.0.0" inherits "^2.0.1" +elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= dependencies: iconv-lite "~0.4.13" end-of-stream@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== dependencies: once "^1.4.0" enhanced-resolve@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" + integrity sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24= dependencies: graceful-fs "^4.1.2" memory-fs "^0.4.0" object-assign "^4.0.1" tapable "^0.2.7" +eol@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/eol/-/eol-0.9.1.tgz#f701912f504074be35c6117a5c4ade49cd547acd" + integrity sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg== + +errlop@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.0.3.tgz#dba29c90cf832c3d2ce469fe515d7e5eef2c6676" + integrity sha512-5VTnt0yikY4LlQEfCXVSqfE6oLj1HVM4zVSvAKMnoYjL/zrb6nqiLowZS4XlG7xENfyj7lpYWvT+wfSCr6dtlA== + dependencies: + editions "^1.3.4" + errno@^0.1.3, errno@~0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== dependencies: prr "~1.0.1" error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" es-abstract@^1.5.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681" + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== dependencies: es-to-primitive "^1.1.1" function-bind "^1.1.1" @@ -2136,23 +2430,27 @@ es-abstract@^1.5.0: is-regex "^1.0.4" es-to-primitive@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== dependencies: - is-callable "^1.1.1" + is-callable "^1.1.4" is-date-object "^1.0.1" - is-symbol "^1.0.1" + is-symbol "^1.0.2" -es5-ext@^0.10.12, es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2: - version "0.10.39" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.39.tgz#fca21b67559277ca4ac1a1ed7048b107b6f76d87" +es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.46" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572" + integrity sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw== dependencies: es6-iterator "~2.0.3" es6-symbol "~3.1.1" + next-tick "1" -es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: +es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= dependencies: d "1" es5-ext "^0.10.35" @@ -2161,6 +2459,7 @@ es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: es6-map@^0.1.3: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= dependencies: d "1" es5-ext "~0.10.14" @@ -2172,6 +2471,7 @@ es6-map@^0.1.3: es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= dependencies: d "1" es5-ext "~0.10.14" @@ -2182,6 +2482,7 @@ es6-set@~0.1.5: es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= dependencies: d "1" es5-ext "~0.10.14" @@ -2189,6 +2490,7 @@ es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8= dependencies: d "1" es5-ext "^0.10.14" @@ -2198,14 +2500,17 @@ es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= dependencies: esprima "^2.7.1" estraverse "^1.9.1" @@ -2217,6 +2522,7 @@ escodegen@1.8.x: escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= dependencies: es6-map "^0.1.3" es6-weak-map "^2.0.1" @@ -2226,10 +2532,12 @@ escope@^3.6.0: eslint-config-standard@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz#87ee0d3c9d95382dc761958cbb23da9eea31e0ba" + integrity sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw== eslint-import-resolver-node@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== dependencies: debug "^2.6.9" resolve "^1.5.0" @@ -2237,13 +2545,15 @@ eslint-import-resolver-node@^0.3.1: eslint-module-utils@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" + integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= dependencies: debug "^2.6.8" pkg-dir "^1.0.0" eslint-plugin-import@^2.10.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.11.0.tgz#15aeea37a67499d848e8e981806d4627b5503816" + version "2.14.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" + integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== dependencies: contains-path "^0.1.0" debug "^2.6.8" @@ -2259,6 +2569,7 @@ eslint-plugin-import@^2.10.0: eslint-plugin-node@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz#bf19642298064379315d7a4b2a75937376fa05e4" + integrity sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw== dependencies: ignore "^3.3.6" minimatch "^3.0.4" @@ -2266,16 +2577,19 @@ eslint-plugin-node@^6.0.1: semver "^5.4.1" eslint-plugin-promise@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz#f4bde5c2c77cdd69557a8f69a24d1ad3cfc9e67e" + version "3.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621" + integrity sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ== eslint-plugin-standard@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz#2a9e21259ba4c47c02d53b2d0c9135d4b1022d47" + integrity sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w== eslint-scope@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2283,10 +2597,12 @@ eslint-scope@^3.7.1: eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== eslint@^4.19.1: version "4.19.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ== dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" @@ -2330,6 +2646,7 @@ eslint@^4.19.1: espree@^3.5.4: version "3.5.4" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== dependencies: acorn "^5.5.0" acorn-jsx "^3.0.0" @@ -2337,42 +2654,51 @@ espree@^3.5.4: esprima@2.7.x, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== dependencies: estraverse "^4.0.0" esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== dependencies: estraverse "^4.1.0" estraverse@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= eth-block-tracker@^2.2.2: version "2.3.1" resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.3.1.tgz#ab6d177e5b50128fa06d7ae9e0489c7484bac95e" + integrity sha512-NamWuMBIl8kmkJFVj8WzGatySTzQPQag4Xr677yFxdVtIxACFbL/dQowk0MzEqIKk93U1TwY3MjVU6mOcwZnKA== dependencies: async-eventemitter ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c eth-query "^2.1.0" @@ -2386,6 +2712,7 @@ eth-block-tracker@^2.2.2: eth-lib@0.1.27, eth-lib@^0.1.26: version "0.1.27" resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.27.tgz#f0b0fd144f865d2d6bf8257a40004f2e75ca1dd6" + integrity sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA== dependencies: bn.js "^4.11.6" elliptic "^6.4.0" @@ -2398,6 +2725,7 @@ eth-lib@0.1.27, eth-lib@^0.1.26: eth-lib@0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca" + integrity sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco= dependencies: bn.js "^4.11.6" elliptic "^6.4.0" @@ -2406,6 +2734,7 @@ eth-lib@0.2.7: eth-lightwallet@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/eth-lightwallet/-/eth-lightwallet-3.0.1.tgz#297022932aa568f4e4eb0873bff257f5e5b78709" + integrity sha512-79vVCETy+4l1b6wuOWwjqPW3Bom5ZK46BgkUNwaXhiMG1rrMRHjpjYEWMqH0JHeCzOzB4HBIFz7eK1/4s6w5nA== dependencies: bitcore-lib "^0.15.0" bitcore-mnemonic "^1.5.0" @@ -2422,6 +2751,7 @@ eth-lightwallet@^3.0.1: eth-query@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" + integrity sha1-1nQdkAAQa1FRDHLbktY2VFam2l4= dependencies: json-rpc-random-id "^1.0.0" xtend "^4.0.1" @@ -2429,6 +2759,7 @@ eth-query@^2.1.0: eth-sig-util@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" + integrity sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA= dependencies: ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" ethereumjs-util "^5.1.1" @@ -2436,6 +2767,7 @@ eth-sig-util@^1.4.2: ethereum-bridge@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/ethereum-bridge/-/ethereum-bridge-0.6.1.tgz#53c93ed7c0e21752a91e5f089a5997e1d6fea228" + integrity sha512-yDTivI85618BoLI71yNRzW6iVcVN2rjnviCIzs0QOCOENj4XpYQhMDGhdqDi8XWDdzTd0Ja/Canuuh3vfE2IcA== dependencies: async "^2.4.1" borc "^2.0.2" @@ -2466,21 +2798,24 @@ ethereum-bridge@^0.6.1: ethereum-common@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" + integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== ethereum-common@^0.0.18: version "0.0.18" resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" + integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= ethereumjs-abi@0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.4.tgz#9ba1bb056492d00c27279f6eccd4d58275912c1a" + integrity sha1-m6G7BWSS0AwnJ59uzNTVgnWRLBo= dependencies: bn.js "^4.10.0" ethereumjs-util "^4.3.0" ethereumjs-abi@^0.6.5, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": version "0.6.5" - resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf" + resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7" dependencies: bn.js "^4.10.0" ethereumjs-util "^5.0.0" @@ -2488,6 +2823,7 @@ ethereumjs-abi@^0.6.5, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereu ethereumjs-account@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" + integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== dependencies: ethereumjs-util "^5.0.0" rlp "^2.0.0" @@ -2496,6 +2832,7 @@ ethereumjs-account@^2.0.3: ethereumjs-block@^1.2.2, ethereumjs-block@~1.7.0: version "1.7.1" resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" + integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== dependencies: async "^2.0.1" ethereum-common "0.2.0" @@ -2503,35 +2840,37 @@ ethereumjs-block@^1.2.2, ethereumjs-block@~1.7.0: ethereumjs-util "^5.0.0" merkle-patricia-tree "^2.1.2" +ethereumjs-common@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-0.4.1.tgz#27690a24a817b058cc3a2aedef9392e8d7d63984" + integrity sha512-ywYGsOeGCsMNWso5Y4GhjWI24FJv9FK7+VyVKiQgXg8ZRDPXJ7F/kJ1CnjtkjTvDF4e0yqU+FWswlqR3bmZQ9Q== + ethereumjs-testrpc-sc@6.1.6: version "6.1.6" resolved "https://registry.yarnpkg.com/ethereumjs-testrpc-sc/-/ethereumjs-testrpc-sc-6.1.6.tgz#290595380b5182814564d4aa38f35b7788aab070" + integrity sha512-iv2qiGBFgk9mn5Nq2enX8dG5WQ7Lk+FCqpnxfPfH4Ns8KLPwttmNOy264nh3SXDJJvcQwz/XnlLteDQVILotbg== dependencies: source-map-support "^0.5.3" ethereumjs-testrpc@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/ethereumjs-testrpc/-/ethereumjs-testrpc-6.0.3.tgz#7a0b87bf3670f92f607f98fa6a78801d9741b124" + integrity sha512-lAxxsxDKK69Wuwqym2K49VpXtBvLEsXr1sryNG4AkvL5DomMdeCBbu3D87UEevKenLHBiT8GTjARwN6Yj039gA== dependencies: webpack "^3.0.0" -ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz#c2304912f6c07af03237ad8675ac036e290dad48" - dependencies: - ethereum-common "^0.0.18" - ethereumjs-util "^5.0.0" - -ethereumjs-tx@^1.3.1: +ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.1, ethereumjs-tx@^1.3.3: version "1.3.7" resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" + integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== dependencies: ethereum-common "^0.0.18" ethereumjs-util "^5.0.0" -ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0: +ethereumjs-util@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6" + integrity sha1-PpQosxfuvaPXJg2FT93alUsfG8Y= dependencies: bn.js "^4.8.0" create-hash "^1.1.2" @@ -2542,6 +2881,7 @@ ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0: ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.3, ethereumjs-util@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz#3e0c0d1741471acf1036052d048623dee54ad642" + integrity sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA== dependencies: bn.js "^4.11.0" create-hash "^1.1.2" @@ -2552,36 +2892,40 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum secp256k1 "^3.0.1" ethereumjs-vm@^2.0.2: - version "2.3.5" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz#e69306737b8a7ea80c633ceb9b7dd561897007de" + version "2.4.0" + resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.4.0.tgz#244f1e35f2755e537a13546111d1a4c159d34b13" + integrity sha512-MJ4lCWa5c6LhahhhvoDKW+YGjK00ZQn0RHHLh4L+WaH1k6Qv7/q3uTluew6sJGNCZdlO0yYMDXYW9qyxLHKlgQ== dependencies: async "^2.1.2" async-eventemitter "^0.2.2" - ethereum-common "0.2.0" ethereumjs-account "^2.0.3" ethereumjs-block "~1.7.0" - ethereumjs-util "^5.1.3" + ethereumjs-common "~0.4.0" + ethereumjs-util "^5.2.0" fake-merkle-patricia-tree "^1.0.1" functional-red-black-tree "^1.0.1" merkle-patricia-tree "^2.1.2" - rustbn.js "~0.1.1" + rustbn.js "~0.2.0" safe-buffer "^5.1.1" ethereumjs-wallet@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz#82763b1697ee7a796be7155da9dfb49b2f98cfdb" + version "0.6.2" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda" + integrity sha512-DHEKPV9lYORM7dL8602dkb+AgdfzCYz2lxpdYQoD3OwG355LLDuivW9rGuLpDMCry/ORyBYV6n+QCo/71SwACg== dependencies: - aes-js "^0.2.3" - bs58check "^1.0.8" - ethereumjs-util "^4.4.0" - hdkey "^0.7.0" + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereumjs-util "^5.2.0" + hdkey "^1.0.0" + safe-buffer "^5.1.2" scrypt.js "^0.2.0" - utf8 "^2.1.1" - uuid "^2.0.1" + utf8 "^3.0.0" + uuid "^3.3.2" ethers@^3.0.15: - version "3.0.15" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-3.0.15.tgz#7cdea4e23025681f69f575bf481b227315e0e7ab" + version "3.0.29" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-3.0.29.tgz#ce8139955b4ed44456eb6764b089bb117c86775d" + integrity sha512-OGyA5pW5xFC5o/ZV5MfIoVp/EdA1QMg2bMJFf7Kznsz8m7IzzbgsPHTCjzSfKQDs/XDphGyRcA7A6bkIeJL4gw== dependencies: aes-js "3.0.0" bn.js "^4.4.0" @@ -2597,6 +2941,7 @@ ethers@^3.0.15: ethjs-abi@0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/ethjs-abi/-/ethjs-abi-0.1.8.tgz#cd288583ed628cdfadaf8adefa3ba1dbcbca6c18" + integrity sha1-zSiFg+1ijN+tr4re+juh28vKbBg= dependencies: bn.js "4.11.6" js-sha3 "0.5.5" @@ -2605,13 +2950,15 @@ ethjs-abi@0.1.8: ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + integrity sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk= dependencies: bn.js "4.11.6" number-to-bn "1.7.0" ethjs-util@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.4.tgz#1c8b6879257444ef4d3f3fbbac2ded12cd997d93" + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" + integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== dependencies: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" @@ -2619,6 +2966,7 @@ ethjs-util@^0.1.3: event-emitter@^0.3.5, event-emitter@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= dependencies: d "1" es5-ext "~0.10.14" @@ -2626,14 +2974,22 @@ event-emitter@^0.3.5, event-emitter@~0.3.5: eventemitter3@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.1.1.tgz#47786bdaa087caf7b1b75e73abc5c7d540158cd0" + integrity sha1-R3hr2qCHyvext15zq8XH1UAVjNA= events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" safe-buffer "^5.1.1" @@ -2641,6 +2997,7 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -2653,12 +3010,14 @@ execa@^0.7.0: expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= dependencies: is-posix-bracket "^0.1.0" expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -2671,16 +3030,18 @@ expand-brackets@^2.1.4: expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= dependencies: fill-range "^2.1.0" express@^4.14.0: - version "4.16.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== dependencies: accepts "~1.3.5" array-flatten "1.1.1" - body-parser "1.18.2" + body-parser "1.18.3" content-disposition "0.5.2" content-type "~1.0.4" cookie "0.3.1" @@ -2697,10 +3058,10 @@ express@^4.14.0: on-finished "~2.3.0" parseurl "~1.3.2" path-to-regexp "0.1.7" - proxy-addr "~2.0.3" - qs "6.5.1" + proxy-addr "~2.0.4" + qs "6.5.2" range-parser "~1.2.0" - safe-buffer "5.1.1" + safe-buffer "5.1.2" send "0.16.2" serve-static "1.13.2" setprototypeof "1.1.0" @@ -2712,45 +3073,48 @@ express@^4.14.0: extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== extended@0.0.6, extended@~0.0.3: version "0.0.6" resolved "https://registry.yarnpkg.com/extended/-/extended-0.0.6.tgz#7fb8bf7b9dae397586e48570acfd642c78e50669" + integrity sha1-f7i/e52uOXWG5IVwrP1kLHjlBmk= dependencies: extender "~0.0.5" extender@~0.0.5: version "0.0.10" resolved "https://registry.yarnpkg.com/extender/-/extender-0.0.10.tgz#589c07482be61a1460b6d81f9c24aa67e8f324cd" + integrity sha1-WJwHSCvmGhRgttgfnCSqZ+jzJM0= dependencies: declare.js "~0.0.4" extendr@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/extendr/-/extendr-2.1.0.tgz#301aa0bbea565f4d2dc8f570f2a22611a8527b56" + integrity sha1-MBqgu+pWX00tyPVw8qImEahSe1Y= dependencies: typechecker "~2.0.1" external-editor@^2.0.4: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" @@ -2759,12 +3123,14 @@ external-editor@^2.0.4: extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= dependencies: is-extglob "^1.0.0" extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" define-property "^1.0.0" @@ -2778,30 +3144,36 @@ extglob@^2.0.4: extract-opts@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/extract-opts/-/extract-opts-2.2.0.tgz#1fa28eba7352c6db480f885ceb71a46810be6d7d" + integrity sha1-H6KOunNSxttID4hc63GkaBC+bX0= dependencies: typechecker "~2.0.1" extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= eyes@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= fake-merkle-patricia-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" + integrity sha1-S4w6z7Ugr635hgsfFM2M40As3dM= dependencies: checkpoint-store "^1.1.0" fast-csv@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/fast-csv/-/fast-csv-2.4.1.tgz#bd7dd268391f729367b59445b8dd0ad026881b26" + integrity sha1-vX3SaDkfcpNntZRFuN0K0CaIGyY= dependencies: extended "0.0.6" is-extended "0.0.10" @@ -2811,52 +3183,48 @@ fast-csv@^2.4.1: fast-deep-equal@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fbjs@^0.8.16: - version "0.8.17" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - -fd-slicer@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= dependencies: pend "~1.2.0" fetch-ponyfill@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" + integrity sha1-rjzl9zLGReq4fkroeTQUcJsjmJM= dependencies: node-fetch "~1.7.1" figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= dependencies: escape-string-regexp "^1.0.5" file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= dependencies: flat-cache "^1.2.1" object-assign "^4.0.1" @@ -2864,22 +3232,27 @@ file-entry-cache@^2.0.0: file-type@^3.8.0: version "3.9.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= file-type@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha1-LdvqfHP/42No365J3DOMBYwritY= file-type@^6.1.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= fill-range@^2.1.0: version "2.2.4" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== dependencies: is-number "^2.1.0" isobject "^2.0.0" @@ -2890,6 +3263,7 @@ fill-range@^2.1.0: fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -2899,6 +3273,7 @@ fill-range@^4.0.0: finalhandler@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== dependencies: debug "2.6.9" encodeurl "~1.0.2" @@ -2911,6 +3286,7 @@ finalhandler@1.1.1: find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" @@ -2918,45 +3294,48 @@ find-up@^1.0.0: find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= dependencies: locate-path "^2.0.0" flat-cache@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + integrity sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE= dependencies: circular-json "^0.3.1" del "^2.0.2" graceful-fs "^4.1.2" write "^0.2.1" -for-each@^0.3.2, for-each@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" +for-each@^0.3.2, for-each@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: - is-function "~1.0.0" + is-callable "^1.1.3" for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= for-own@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= dependencies: for-in "^1.0.1" -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@~2.3.1, form-data@~2.3.2: +form-data@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + integrity sha1-SXBJi+YEwgwAXU9cI67NIda0kJk= dependencies: asynckit "^0.4.0" combined-stream "1.0.6" @@ -2965,24 +3344,29 @@ form-data@~2.3.1, form-data@~2.3.2: forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= dependencies: graceful-fs "^4.1.2" jsonfile "^2.1.0" @@ -2993,6 +3377,7 @@ fs-extra@^0.30.0: fs-extra@^2.0.0, fs-extra@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35" + integrity sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU= dependencies: graceful-fs "^4.1.2" jsonfile "^2.1.0" @@ -3000,6 +3385,7 @@ fs-extra@^2.0.0, fs-extra@^2.1.2: fs-extra@^4.0.2: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -3008,6 +3394,7 @@ fs-extra@^4.0.2: fs-extra@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -3016,12 +3403,14 @@ fs-extra@^5.0.0: fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== dependencies: minipass "^2.2.1" fs-promise@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-2.0.3.tgz#f64e4f854bcf689aa8bddcba268916db3db46854" + integrity sha1-9k5PhUvPaJqovdy6JokW2z20aFQ= dependencies: any-promise "^1.3.0" fs-extra "^2.0.0" @@ -3031,21 +3420,25 @@ fs-promise@^2.0.0: fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fs@0.0.1-security: version "0.0.1-security" resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + integrity sha1-invTcYa23d84E/I4WLV+yq9eQdQ= -fsevents@^1.0.0, fsevents@^1.1.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.3.tgz#08292982e7059f6674c93d8b829c1e8604979ac0" +fsevents@^1.0.0, fsevents@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== dependencies: nan "^2.9.2" - node-pre-gyp "^0.9.0" + node-pre-gyp "^0.10.0" fstream@^1.0.2, fstream@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" @@ -3055,20 +3448,24 @@ fstream@^1.0.2, fstream@^1.0.8: function-bind@^1.0.2, function-bind@^1.1.1, function-bind@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= ganache-cli@^6.1.8: version "6.1.8" resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.1.8.tgz#49a8a331683a9652183f82ef1378d17e1814fcd3" + integrity sha512-yXzteu4SIgUL31mnpm9j+x6dpHUw0p/nsRVkcySKq0w+1vDxH9jMErP1QhZAJuTVE6ni4nfvGSNkaQx5cD3jfg== dependencies: source-map-support "^0.5.3" gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -3080,12 +3477,14 @@ gauge@~2.7.3: wide-align "^1.1.0" get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== get-stream@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= dependencies: object-assign "^4.0.1" pinkie-promise "^2.0.0" @@ -3093,20 +3492,24 @@ get-stream@^2.2.0: get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= dependencies: assert-plus "^1.0.0" glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= dependencies: glob-parent "^2.0.0" is-glob "^2.0.0" @@ -3114,19 +3517,22 @@ glob-base@^0.3.0: glob-parent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= dependencies: is-glob "^2.0.0" glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.2: +glob@7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3138,6 +3544,7 @@ glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.2: glob@^5.0.15: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= dependencies: inflight "^1.0.4" inherits "2" @@ -3145,9 +3552,22 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.2: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@~6.0.4: version "6.0.4" resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= dependencies: inflight "^1.0.4" inherits "2" @@ -3158,21 +3578,25 @@ glob@~6.0.4: global@~4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= dependencies: min-document "^2.19.0" process "~0.5.1" globals@^11.0.1: - version "11.5.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.5.0.tgz#6bc840de6771173b191f13d3a9c94d441ee92642" + version "11.8.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d" + integrity sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA== globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= dependencies: array-union "^1.0.1" arrify "^1.0.0" @@ -3184,6 +3608,7 @@ globby@^5.0.0: got@7.1.0, got@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== dependencies: decompress-response "^3.2.0" duplexer3 "^0.1.4" @@ -3200,46 +3625,46 @@ got@7.1.0, got@^7.1.0: url-parse-lax "^1.0.0" url-to-options "^1.0.1" -graceful-fs@*, graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@*, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= growl@1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + integrity sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q== -growl@1.10.5: +growl@1.10.5, "growl@~> 1.10.0": version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== handlebars@^4.0.1: - version "4.0.11" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== dependencies: - async "^1.4.0" + async "^2.5.0" optimist "^0.6.1" - source-map "^0.4.4" + source-map "^0.6.1" optionalDependencies: - uglify-js "^2.6" + uglify-js "^3.1.4" har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= har-validator@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" + integrity sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA== dependencies: ajv "^5.3.0" har-schema "^2.0.0" @@ -3247,38 +3672,51 @@ har-validator@~5.1.0: has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbol-support-x@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= has-to-string-tag-x@^1.2.0: version "1.4.1" resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== dependencies: has-symbol-support-x "^1.4.1" has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -3287,6 +3725,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -3295,89 +3734,79 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1, has@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" +has@^1.0.1, has@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: - function-bind "^1.0.2" + function-bind "^1.1.1" hash-base@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== dependencies: inherits "^2.0.3" - minimalistic-assert "^1.0.0" - -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" + minimalistic-assert "^1.0.1" -hdkey@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-0.7.1.tgz#caee4be81aa77921e909b8d228dd0f29acaee632" +hdkey@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" + integrity sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ== dependencies: coinstring "^2.0.0" + safe-buffer "^5.1.1" secp256k1 "^3.0.1" he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: hash.js "^1.0.3" minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@4.x.x: - version "4.2.1" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" - home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.1" hosted-git-info@^2.1.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222" + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== -http-errors@1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" - dependencies: - depd "1.1.1" - inherits "2.0.3" - setprototypeof "1.0.3" - statuses ">= 1.3.1 < 2" - -http-errors@~1.6.2: +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= dependencies: depd "~1.1.2" inherits "2.0.3" @@ -3387,10 +3816,12 @@ http-errors@~1.6.2: http-https@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs= http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" @@ -3399,10 +3830,12 @@ http-signature@~1.2.0: https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= i18n@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/i18n/-/i18n-0.8.3.tgz#2d8cf1c24722602c2041d01ba6ae5eaa51388f0e" + integrity sha1-LYzxwkciYCwgQdAbpq5eqlE4jw4= dependencies: debug "*" make-plural "^3.0.3" @@ -3411,37 +3844,41 @@ i18n@^0.8.3: mustache "*" sprintf-js ">=1.0.3" -iconv-lite@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - -iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.4: - version "1.1.11" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.11.tgz#c16384ffe00f5b7835824e67b6f2bd44a5229455" +iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.8: +ieee754@^1.1.4, ieee754@^1.1.8: version "1.1.12" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== ignore-walk@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== dependencies: minimatch "^3.0.4" ignore@^3.3.3, ignore@^3.3.6: - version "3.3.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b" + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== ignorefs@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ignorefs/-/ignorefs-1.2.0.tgz#da59fb858976e4a5e43702ccd1f282fdbc9e5756" + integrity sha1-2ln7hYl25KXkNwLM0fKC/byeV1Y= dependencies: editions "^1.3.3" ignorepatterns "^1.1.0" @@ -3449,22 +3886,27 @@ ignorefs@^1.0.0: ignorepatterns@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ignorepatterns/-/ignorepatterns-1.1.0.tgz#ac8f436f2239b5dfb66d5f0d3a904a87ac67cc5e" + integrity sha1-rI9DbyI5td+2bV8NOpBKh6xnzF4= immediate@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" + integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw= imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -3472,18 +3914,22 @@ inflight@^1.0.4: inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= inherits@2.0.1, inherits@=2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== inquirer@^3.0.6: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -3503,76 +3949,91 @@ inquirer@^3.0.6: interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= invariant@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= -ipaddr.js@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= dependencies: binary-extensions "^1.0.0" is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-builtin-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= dependencies: builtin-modules "^1.0.0" -is-callable@^1.1.1, is-callable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" is-data-descriptor "^0.1.4" @@ -3581,6 +4042,7 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" is-data-descriptor "^1.0.0" @@ -3589,220 +4051,261 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= is-equal-shallow@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= dependencies: is-primitive "^2.0.0" is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extended@0.0.10, is-extended@~0.0.3, is-extended@~0.0.8: version "0.0.10" resolved "https://registry.yarnpkg.com/is-extended/-/is-extended-0.0.10.tgz#244e140df75bb1c9a3106f412ff182fb534a6d62" + integrity sha1-JE4UDfdbscmjEG9BL/GC+1NKbWI= dependencies: extended "~0.0.3" is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= dependencies: number-is-nan "^1.0.0" is-fn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" + integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw= is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= -is-function@^1.0.1, is-function@~1.0.0: +is-function@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU= is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= dependencies: is-extglob "^1.0.0" is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= dependencies: is-extglob "^2.1.0" is-glob@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= dependencies: is-extglob "^2.1.1" is-hex-prefixed@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" + integrity sha1-fY035q135dEnFIkTxXPggtd39VQ= is-nan@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.2.1.tgz#9faf65b6fb6db24b7f5c0628475ea71f988401e2" + integrity sha1-n69ltvttskt/XAYoR16nH5iEAeI= dependencies: define-properties "^1.1.1" is-natural-number@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= dependencies: kind-of "^3.0.2" is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-number@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= is-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" - -is-odd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" - dependencies: - is-number "^4.0.0" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= is-path-in-cwd@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== dependencies: is-path-inside "^1.0.0" is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= dependencies: path-is-inside "^1.0.1" is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= is-promise@^2.1, is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= dependencies: has "^1.0.1" is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-symbol@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isomorphic-fetch@^2.1.1, isomorphic-fetch@^2.2.0: +isomorphic-fetch@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= dependencies: node-fetch "^1.0.1" whatwg-fetch ">=0.10.0" @@ -3810,10 +4313,12 @@ isomorphic-fetch@^2.1.1, isomorphic-fetch@^2.2.0: isstream@0.1.x, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= istanbul@^0.4.5: version "0.4.5" resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= dependencies: abbrev "1.0.x" async "1.x" @@ -3833,6 +4338,7 @@ istanbul@^0.4.5: isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== dependencies: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" @@ -3840,30 +4346,37 @@ isurl@^1.0.0-alpha5: js-sha3@0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a" + integrity sha1-uvDA6MVK1ZA0R9+Wreekobynmko= js-sha3@0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= js-sha3@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243" + integrity sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM= js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" - -js-tokens@^3.0.0, js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= "js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@3.x, js-yaml@^3.6.1, js-yaml@^3.9.1: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" +js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.9.1: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -3871,91 +4384,114 @@ js-yaml@3.x, js-yaml@^3.6.1, js-yaml@^3.9.1: jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= json-loader@^0.5.4: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" + integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== json-rpc-engine@^3.6.0: - version "3.6.3" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.6.3.tgz#df80459da8bc9020bfb5372b3b70e6c20ea07d40" + version "3.8.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" + integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== dependencies: async "^2.0.1" - babel-preset-env "^1.3.2" + babel-preset-env "^1.7.0" babelify "^7.3.0" - clone "^2.1.1" json-rpc-error "^2.0.0" promise-to-callback "^1.0.0" + safe-event-emitter "^1.0.1" json-rpc-error@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" + integrity sha1-p6+cICg4tekFxyUOVH8a/3cligI= dependencies: inherits "^2.0.1" json-rpc-random-id@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" + integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg= json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= dependencies: jsonify "~0.0.0" json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json-text-sequence@^0.1: version "0.1.1" resolved "https://registry.yarnpkg.com/json-text-sequence/-/json-text-sequence-0.1.1.tgz#a72f217dc4afc4629fff5feb304dc1bd51a2f3d2" + integrity sha1-py8hfcSvxGKf/1/rME3BvVGi89I= dependencies: delimit-stream "0.1.0" json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= optionalDependencies: graceful-fs "^4.1.6" jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= optionalDependencies: graceful-fs "^4.1.6" jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= dependencies: assert-plus "1.0.0" extsprintf "1.3.0" @@ -3965,6 +4501,7 @@ jsprim@^1.2.2: keccak@^1.0.2: version "1.4.0" resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80" + integrity sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw== dependencies: bindings "^1.2.1" inherits "^2.0.3" @@ -3974,6 +4511,7 @@ keccak@^1.0.2: keccakjs@^0.2.0, keccakjs@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.1.tgz#1d633af907ef305bbf9f2fa616d56c44561dfa4d" + integrity sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0= dependencies: browserify-sha3 "^0.0.1" sha3 "^1.1.0" @@ -3981,62 +4519,74 @@ keccakjs@^0.2.0, keccakjs@^0.2.1: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= optionalDependencies: graceful-fs "^4.1.9" lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= dependencies: invert-kv "^1.0.0" lcov-parse@^0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + integrity sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM= level-codec@~7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" + integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== level-errors@^1.0.3: version "1.1.2" resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" + integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== dependencies: errno "~0.1.1" level-errors@~1.0.3: version "1.0.5" resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" + integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== dependencies: errno "~0.1.1" level-iterator-stream@~1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" + integrity sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0= dependencies: inherits "^2.0.1" level-errors "^1.0.3" @@ -4046,6 +4596,7 @@ level-iterator-stream@~1.3.0: level-ws@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" + integrity sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos= dependencies: readable-stream "~1.0.15" xtend "~2.1.1" @@ -4053,6 +4604,7 @@ level-ws@0.0.0: levelup@^1.2.1: version "1.3.9" resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" + integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== dependencies: deferred-leveldown "~1.2.1" level-codec "~7.0.0" @@ -4065,6 +4617,7 @@ levelup@^1.2.1: levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" @@ -4072,6 +4625,7 @@ levn@^0.3.0, levn@~0.3.0: load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -4082,6 +4636,7 @@ load-json-file@^1.0.0: load-json-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -4089,12 +4644,14 @@ load-json-file@^2.0.0: strip-bom "^3.0.0" loader-runner@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + version "2.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" + integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== loader-utils@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= dependencies: big.js "^3.1.3" emojis-list "^2.0.0" @@ -4103,6 +4660,7 @@ loader-utils@^1.1.0: locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= dependencies: p-locate "^2.0.0" path-exists "^3.0.0" @@ -4110,54 +4668,54 @@ locate-path@^2.0.0: lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= -lodash@4.x, lodash@^4.14.0, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.5, lodash@^4.3.0: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" - -lodash@=4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash@^4.13.1: +lodash@4.x, lodash@^4.13.1, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== -lodash@^4.17.4: - version "4.17.5" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" +lodash@=4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= -log-driver@^1.2.5: +log-driver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" + integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== long-timeout@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/long-timeout/-/long-timeout-0.1.1.tgz#9721d788b47e0bcb5a24c2e2bee1a0da55dab514" + integrity sha1-lyHXiLR+C8taJMLivuGg2lXatRQ= longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -loose-envify@^1.1.0, loose-envify@^1.3.1: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lowercase-keys@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== lru-cache@^4.0.1: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" @@ -4165,65 +4723,78 @@ lru-cache@^4.0.1: lru-queue@0.1: version "0.1.0" resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= dependencies: es5-ext "~0.10.2" ltgt@~2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU= make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== dependencies: pify "^3.0.0" make-plural@^3.0.3, make-plural@~3.0.3: version "3.0.6" resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-3.0.6.tgz#2033a03bac290b8f3bb91258f65b9df7e8b01ca7" + integrity sha1-IDOgO6wpC487uRJY9lud9+iwHKc= optionalDependencies: minimist "^1.2.0" map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" math-interval-parser@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/math-interval-parser/-/math-interval-parser-1.1.0.tgz#dbeda5b06b3249973c6df6170fde2386f0afd893" + integrity sha1-2+2lsGsySZc8bfYXD94jhvCv2JM= dependencies: xregexp "^2.0.0" math-random@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= md5.js@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" inherits "^2.0.1" + safe-buffer "^5.1.2" media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= dependencies: mimic-fn "^1.0.0" memdown@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" + integrity sha1-tOThkhdGZP+65BNhqlAPMRnv4hU= dependencies: abstract-leveldown "~2.7.1" functional-red-black-tree "^1.0.1" @@ -4232,22 +4803,24 @@ memdown@^1.0.0: ltgt "~2.2.0" safe-buffer "~5.1.1" -memoizee@^0.4.3: - version "0.4.12" - resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.12.tgz#780e99a219c50c549be6d0fc61765080975c58fb" +memoizee@^0.4.14: + version "0.4.14" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" + integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== dependencies: d "1" - es5-ext "^0.10.30" + es5-ext "^0.10.45" es6-weak-map "^2.0.2" event-emitter "^0.3.5" is-promise "^2.1" lru-queue "0.1" next-tick "1" - timers-ext "^0.1.2" + timers-ext "^0.1.5" memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= dependencies: errno "^0.1.3" readable-stream "^2.0.1" @@ -4255,14 +4828,17 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= merkle-patricia-tree@^2.1.2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz#7d4e7263a9c85c1679187cad4a6d71f48d524c71" + version "2.3.2" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" + integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== dependencies: async "^1.4.2" ethereumjs-util "^5.0.0" @@ -4276,6 +4852,7 @@ merkle-patricia-tree@^2.1.2: messageformat@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/messageformat/-/messageformat-0.3.1.tgz#e58fff8245e9b3971799e5b43db58b3e9417f5a2" + integrity sha1-5Y//gkXps5cXmeW0PbWLPpQX9aI= dependencies: async "~1.5.2" glob "~6.0.4" @@ -4286,10 +4863,12 @@ messageformat@^0.3.1: methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^2.1.5: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= dependencies: arr-diff "^2.0.0" array-unique "^0.2.1" @@ -4305,9 +4884,10 @@ micromatch@^2.1.5: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.1.4: +micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -4326,90 +4906,96 @@ micromatch@^3.1.4: miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@~1.33.0: - version "1.33.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" +mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" + integrity sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw== -mime-db@~1.35.0: - version "1.35.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47" - -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.17, mime-types@~2.1.18: - version "2.1.18" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.18, mime-types@~2.1.19: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + integrity sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A== dependencies: - mime-db "~1.33.0" - -mime-types@~2.1.19: - version "2.1.19" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0" - dependencies: - mime-db "~1.35.0" + mime-db "~1.36.0" mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== mimic-response@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= dependencies: dom-walk "^0.1.0" -minimalistic-assert@^1.0.0: +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= "minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@^1.2.0, minimist@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.2.1, minipass@^2.2.4: - version "2.3.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.0.tgz#2e11b1c46df7fe7f1afbe9a490280add21ffe384" +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" + integrity sha512-mlouk1OHlaUE8Odt1drMtG1bAJA4ZA6B/ehysgV0LUIrDHdKgo1KorZq3pK0b/7Z7LJIQ12MNM6aC+Tn6lUZ5w== dependencies: - safe-buffer "^5.1.1" + safe-buffer "^5.1.2" yallist "^3.0.0" minizlib@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + version "1.1.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" + integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== dependencies: minipass "^2.2.1" mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" @@ -4417,18 +5003,21 @@ mixin-deep@^1.2.0: mkdirp-promise@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE= dependencies: mkdirp "*" mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" mocha@^4.0.1, mocha@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.1.0.tgz#7d86cfbcf35cb829e2754c32e17355ec05338794" + integrity sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA== dependencies: browser-stdout "1.3.0" commander "2.11.0" @@ -4444,6 +5033,7 @@ mocha@^4.0.1, mocha@^4.1.0: mocha@^5.0.1: version "5.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== dependencies: browser-stdout "1.3.1" commander "2.15.1" @@ -4458,68 +5048,94 @@ mocha@^5.0.1: supports-color "5.4.0" mock-fs@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.5.0.tgz#75245b966f7e3defe197b03454af9c5b355594b7" + version "4.7.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.7.0.tgz#9f17e219cacb8094f4010e0a8c38589e2b33c299" + integrity sha512-WlQNtUlzMRpvLHf8dqeUmNqfdPjGY29KrJF50Ldb4AcL+vQeR8QH3wQcFMgrhTwb1gHjZn9xggho+84tBskLgA== moment-timezone@^0.5.0: version "0.5.21" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.21.tgz#3cba247d84492174dbf71de2a9848fa13207b845" + integrity sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A== dependencies: moment ">= 2.9.0" "moment@>= 2.9.0", moment@^2.22.2: version "2.22.2" resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" + integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= mout@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/mout/-/mout-0.11.1.tgz#ba3611df5f0e5b1ffbfd01166b8f02d1f5fa2b99" + integrity sha1-ujYR318OWx/7/QEWa48C0fX6K5k= ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== multihashes@^0.4.5: version "0.4.14" resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.14.tgz#774db9a161f81a8a27dc60788f91248e020f5244" + integrity sha512-V/g/EIN6nALXfS/xHUAgtfPP3mn3sPIF/i9beuGKf25QXS2QZYCpeVJbDPEannkz32B2fihzCe2D/KMrbcmefg== dependencies: bs58 "^4.0.1" varint "^5.0.0" -mustache@*, mustache@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.1.tgz#ef5db3c0d11f1640e9baa47f4e65ba0c3fcd82b9" +mustache@*: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-3.0.0.tgz#3de22dd9ba38152f7355399a953dd4528c403338" + integrity sha512-bhBDkK/PioIbtQzRIbGUGypvc3MC4c389QnJt8KDIEJ666OidRPoXAQAHPivikfS3JkMEaWoPvcDL7YrQxtSwg== + +mustache@^2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.2.tgz#a6d4d9c3f91d13359ab889a812954f9230a3d0c5" + integrity sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ== mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= mz@^2.6.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== dependencies: any-promise "^1.0.0" object-assign "^4.0.1" thenify-all "^1.0.0" -nan@2.10.0, nan@^2.0.8, nan@^2.2.1, nan@^2.3.3, nan@^2.9.2: +nan@2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== + +nan@^2.0.8, nan@^2.2.1, nan@^2.3.3, nan@^2.9.2: + version "2.11.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= nanomatch@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" define-property "^2.0.2" extend-shallow "^3.0.2" fragment-cache "^0.2.1" - is-odd "^2.0.0" is-windows "^1.0.2" kind-of "^6.0.2" object.pick "^1.3.0" @@ -4530,10 +5146,12 @@ nanomatch@^1.2.9: natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -needle@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== dependencies: debug "^2.1.2" iconv-lite "^0.4.4" @@ -4542,22 +5160,27 @@ needle@^2.2.0: negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= neo-async@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" + version "2.5.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.2.tgz#489105ce7bc54e709d736b195f82135048c50fcc" + integrity sha512-vdqTKI9GBIYcAEbFAcpKPErKINfPF5zIuz3/niBfq8WUZjpT2tytLlFVrBgWdOtqI4uaA/Rb6No0hux39XXDuw== next-tick@1: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= node-async-loop@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/node-async-loop/-/node-async-loop-1.2.2.tgz#c5870299bf6477b780c88b431aa5b37733f55a3d" + integrity sha1-xYcCmb9kd7eAyItDGqWzdzP1Wj0= node-cache@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-4.2.0.tgz#48ac796a874e762582692004a376d26dfa875811" + integrity sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw== dependencies: clone "2.x" lodash "4.x" @@ -4565,6 +5188,7 @@ node-cache@^4.1.1: node-fetch@^1.0.1, node-fetch@~1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== dependencies: encoding "^0.1.11" is-stream "^1.0.1" @@ -4572,6 +5196,7 @@ node-fetch@^1.0.1, node-fetch@~1.7.1: node-libs-browser@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg== dependencies: assert "^1.1.1" browserify-zlib "^0.2.0" @@ -4597,17 +5222,18 @@ node-libs-browser@^2.0.0: util "^0.10.3" vm-browserify "0.0.4" -node-pre-gyp@^0.9.0: - version "0.9.1" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz#f11c07516dd92f87199dbc7e1838eab7cd56c9e0" +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" - needle "^2.2.0" + needle "^2.2.1" nopt "^4.0.1" npm-packlist "^1.1.6" npmlog "^4.0.2" - rc "^1.1.7" + rc "^1.2.7" rimraf "^2.6.1" semver "^5.3.0" tar "^4" @@ -4615,6 +5241,7 @@ node-pre-gyp@^0.9.0: node-schedule@^1.2.3: version "1.3.0" resolved "https://registry.yarnpkg.com/node-schedule/-/node-schedule-1.3.0.tgz#e7a7e816a7f2550d5b170bd106e765db28bdf030" + integrity sha512-NNwO9SUPjBwFmPh3vXiPVEhJLn4uqYmZYvJV358SRGM06BR4UoIqxJpeJwDDXB6atULsgQA97MfD1zMd5xsu+A== dependencies: cron-parser "^2.4.0" long-timeout "0.1.1" @@ -4623,12 +5250,14 @@ node-schedule@^1.2.3: nopt@3.x, nopt@~3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= dependencies: abbrev "1" nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= dependencies: abbrev "1" osenv "^0.1.4" @@ -4636,6 +5265,7 @@ nopt@^4.0.1: normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -4645,16 +5275,19 @@ normalize-package-data@^2.3.2: normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" npm-bundled@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== npm-packlist@^1.1.6: - version "1.1.10" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" + version "1.1.12" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" + integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -4662,12 +5295,14 @@ npm-packlist@^1.1.6: npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -4677,29 +5312,30 @@ npmlog@^4.0.2: number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" + integrity sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA= dependencies: bn.js "4.11.6" strip-hex-prefix "1.0.0" -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== object-assign@^4, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" @@ -4708,32 +5344,38 @@ object-copy@^0.1.0: object-extended@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/object-extended/-/object-extended-0.0.7.tgz#84fd23f56b15582aeb3e88b05cb55d2432d68a33" + integrity sha1-hP0j9WsVWCrrPoiwXLVdJDLWijM= dependencies: array-extended "~0.0.4" extended "~0.0.3" is-extended "~0.0.3" -object-inspect@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.5.0.tgz#9d876c11e40f485c79215670281b767488f9bfe3" +object-inspect@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== -object-keys@^1.0.8: - version "1.0.11" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" +object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== object-keys@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= dependencies: for-own "^0.1.4" is-extendable "^0.1.1" @@ -4741,40 +5383,47 @@ object.omit@^2.0.0: object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" oboe@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.3.tgz#2b4865dbd46be81225713f4e9bfe4bcf4f680a4f" + integrity sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8= dependencies: http-https "^1.0.0" on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= dependencies: mimic-fn "^1.0.0" openzeppelin-solidity@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/openzeppelin-solidity/-/openzeppelin-solidity-1.10.0.tgz#d77eee6653f5958d051318a61ba0b436f92216c0" + integrity sha512-igkrumQQ2lrN2zjeQV4Dnb0GpTBj1fzMcd8HPyBUqwI0hhuscX/HzXiqKT6gFQl1j9Wy/ppVVs9fqL/foF7Gmg== optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= dependencies: minimist "~0.0.1" wordwrap "~0.0.2" @@ -4782,6 +5431,7 @@ optimist@^0.6.1: optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= dependencies: deep-is "~0.1.3" fast-levenshtein "~2.0.4" @@ -4793,24 +5443,29 @@ optionator@^0.8.1, optionator@^0.8.2: original-require@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/original-require/-/original-require-1.0.1.tgz#0f130471584cd33511c5ec38c8d59213f9ac5e20" + integrity sha1-DxMEcVhM0zURxew4yNWSE/msXiA= os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-locale@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= dependencies: lcid "^1.0.0" os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== dependencies: execa "^0.7.0" lcid "^1.0.0" @@ -4819,10 +5474,12 @@ os-locale@^2.0.0: os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" @@ -4830,40 +5487,48 @@ osenv@^0.1.4: p-cancelable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= p-limit@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= dependencies: p-limit "^1.1.0" p-timeout@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= dependencies: p-finally "^1.0.0" p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== parse-asn1@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" @@ -4874,6 +5539,7 @@ parse-asn1@^5.0.0: parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= dependencies: glob-base "^0.3.0" is-dotfile "^1.0.0" @@ -4883,6 +5549,7 @@ parse-glob@^3.0.4: parse-headers@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" + integrity sha1-aug6eqJanZtwCswoaYzR8e1+lTY= dependencies: for-each "^0.3.2" trim "0.0.1" @@ -4890,58 +5557,71 @@ parse-headers@^2.0.0: parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= dependencies: error-ex "^1.2.0" parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= path-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= dependencies: pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= dependencies: graceful-fs "^4.1.2" pify "^2.0.0" @@ -4950,12 +5630,14 @@ path-type@^1.0.0: path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= dependencies: pify "^2.0.0" pbkdf2@^3.0.3: - version "3.0.16" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -4966,155 +5648,182 @@ pbkdf2@^3.0.3: pegjs@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/pegjs/-/pegjs-0.10.0.tgz#cf8bafae6eddff4b5a7efb185269eaaf4610ddbd" + integrity sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0= pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pkg-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= dependencies: find-up "^1.0.0" pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= pragma-singleton@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pragma-singleton/-/pragma-singleton-1.0.3.tgz#6894317bb8d47157e59de2a4a009db7e6f63e30e" + integrity sha1-aJQxe7jUcVflneKkoAnbfm9j4w4= prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +prettier@^1.14.3: + version "1.14.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" + integrity sha512-qZDVnCrnpsRJJq5nSsiHCE3BYMED2OtsI+cmzIzF1QIfqm5ALf8tEJcO27zV1gKNKRPdhjO0dNWnrzssDQ1tFg== -private@^0.1.6, private@^0.1.7, private@^0.1.8: +private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= process@~0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + integrity sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8= promise-to-callback@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" + integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc= dependencies: is-fn "^1.0.0" set-immediate-shim "^1.0.1" -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - dependencies: - asap "~2.0.3" - -prop-types@^15.6.0: +prop-types@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102" + integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ== dependencies: loose-envify "^1.3.1" object-assign "^4.1.1" -proxy-addr@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" +proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== dependencies: forwarded "~0.1.2" - ipaddr.js "1.6.0" + ipaddr.js "1.8.0" prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24: version "1.1.29" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== public-encrypt@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" browserify-rsa "^4.0.0" create-hash "^1.1.0" parse-asn1 "^5.0.0" randombytes "^2.0.1" + safe-buffer "^5.1.2" punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= punycode@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - -qs@6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@~6.5.1, qs@~6.5.2: +qs@6.5.2, qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== query-string@^5.0.1: version "5.1.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== dependencies: decode-uri-component "^0.2.0" object-assign "^4.1.0" @@ -5123,14 +5832,17 @@ query-string@^5.0.1: querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= randomatic@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.0.0.tgz#d35490030eb4f7578de292ce6dfb04a91a128923" + version "3.1.0" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" + integrity sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ== dependencies: is-number "^4.0.0" kind-of "^6.0.0" @@ -5139,12 +5851,14 @@ randomatic@^3.0.0: randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" safe-buffer "^5.1.0" @@ -5152,50 +5866,57 @@ randomfill@^1.0.3: randomhex@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/randomhex/-/randomhex-0.1.5.tgz#baceef982329091400f2a2912c6cd02f1094f585" + integrity sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU= range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= -raw-body@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== dependencies: bytes "3.0.0" - http-errors "1.6.2" - iconv-lite "0.4.19" + http-errors "1.6.3" + iconv-lite "0.4.23" unpipe "1.0.0" -rc@^1.1.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.7.tgz#8a10ca30d588d00464360372b890d06dacd02297" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: - deep-extend "^0.5.1" + deep-extend "^0.6.0" ini "~1.3.0" minimist "^1.2.0" strip-json-comments "~2.0.1" react-dom@^16.2.0: - version "16.4.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.2.tgz#4afed569689f2c561d2b8da0b819669c38a0bda4" + version "16.5.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.5.2.tgz#b69ee47aa20bab5327b2b9d7c1fe2a30f2cfa9d7" + integrity sha512-RC8LDw8feuZOHVgzEf7f+cxBr/DnKdqp56VU0lAs1f4UfKc4cU8wU4fTq/mgnvynLQo8OtlPC19NUFh/zjZPuA== dependencies: - fbjs "^0.8.16" loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.0" + prop-types "^15.6.2" + schedule "^0.5.0" react@^16.2.0: - version "16.4.2" - resolved "https://registry.yarnpkg.com/react/-/react-16.4.2.tgz#2cd90154e3a9d9dd8da2991149fdca3c260e129f" + version "16.5.2" + resolved "https://registry.yarnpkg.com/react/-/react-16.5.2.tgz#19f6b444ed139baa45609eee6dc3d318b3895d42" + integrity sha512-FDCSVd3DjVTmbEAjUNX6FgfAmQ+ypJfHUsqUJOYNCBUp1h8lqmtC+0mXJ+JjsWx4KAVTkk1vKd1hLQPvEviSuw== dependencies: - fbjs "^0.8.16" loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.0" + prop-types "^15.6.2" + schedule "^0.5.0" read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= dependencies: find-up "^1.0.0" read-pkg "^1.0.0" @@ -5203,6 +5924,7 @@ read-pkg-up@^1.0.1: read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= dependencies: find-up "^2.0.0" read-pkg "^2.0.0" @@ -5210,6 +5932,7 @@ read-pkg-up@^2.0.0: read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= dependencies: load-json-file "^1.0.0" normalize-package-data "^2.3.2" @@ -5218,6 +5941,7 @@ read-pkg@^1.0.0: read-pkg@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= dependencies: load-json-file "^2.0.0" normalize-package-data "^2.3.2" @@ -5226,15 +5950,17 @@ read-pkg@^2.0.0: readable-stream@^1.0.33: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= dependencies: core-util-is "~1.0.0" inherits "~2.0.1" isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -5247,6 +5973,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable readable-stream@~1.0.15: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -5254,39 +5981,45 @@ readable-stream@~1.0.15: string_decoder "~0.10.x" readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" + graceful-fs "^4.1.11" + micromatch "^3.1.10" readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" readline-sync@^1.4.9: version "1.4.9" resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.9.tgz#3eda8e65f23cd2a17e61301b1f0003396af5ecda" + integrity sha1-PtqOZfI80qF+YTAbHwADOWr17No= rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= dependencies: resolve "^1.1.6" regenerate@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== dependencies: babel-runtime "^6.18.0" babel-types "^6.19.0" @@ -5295,12 +6028,14 @@ regenerator-transform@^0.10.0: regex-cache@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== dependencies: is-equal-shallow "^0.1.3" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" @@ -5308,10 +6043,12 @@ regex-not@^1.0.0, regex-not@^1.0.2: regexpp@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw== regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= dependencies: regenerate "^1.2.1" regjsgen "^0.2.0" @@ -5320,88 +6057,72 @@ regexpu-core@^2.0.0: regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= regjsparser@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= dependencies: is-finite "^1.0.0" req-cwd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-1.0.1.tgz#0d73aeae9266e697a78f7976019677e76acf0fff" + integrity sha1-DXOurpJm5penj3l2AZZ352rPD/8= dependencies: req-from "^1.0.1" req-from@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/req-from/-/req-from-1.0.1.tgz#bf81da5147947d32d13b947dc12a58ad4587350e" + integrity sha1-v4HaUUeUfTLRO5R9wSpYrUWHNQ4= dependencies: resolve-from "^2.0.0" request-promise-core@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY= dependencies: lodash "^4.13.1" request-promise@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" + integrity sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ= dependencies: bluebird "^3.5.0" request-promise-core "1.1.1" stealthy-require "^1.1.0" tough-cookie ">=2.3.3" -request@^2.67.0, request@^2.79.0: - version "2.85.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -request@^2.81.0: +request@^2.67.0, request@^2.79.0, request@^2.81.0, request@^2.85.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -5427,18 +6148,22 @@ request@^2.81.0: require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= require-from-string@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" @@ -5446,34 +6171,41 @@ require-uncached@^1.0.3: resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c= resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@1.1.x: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= resolve@^1.1.6, resolve@^1.3.3, resolve@^1.5.0, resolve@^1.6.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== dependencies: path-parse "^1.0.5" -resolve@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" +resolve@~1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" + integrity sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw== dependencies: path-parse "^1.0.5" restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= dependencies: onetime "^2.0.0" signal-exit "^3.0.2" @@ -5481,107 +6213,139 @@ restore-cursor@^2.0.0: resumer@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= dependencies: through "~2.3.4" ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= dependencies: align-text "^0.1.1" rimraf@2, rimraf@^2.2.8, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== dependencies: glob "^7.0.5" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: hash-base "^3.0.0" inherits "^2.0.1" rlp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.0.0.tgz#9db384ff4b89a8f61563d92395d8625b18f3afb0" + version "2.1.0" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.1.0.tgz#e4f9886d5a982174f314543831e36e1a658460f9" + integrity sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA== + dependencies: + safe-buffer "^5.1.1" run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= dependencies: is-promise "^2.1.0" -rustbn.js@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.1.2.tgz#979fa0f9562216dd667c9d2cd179ae5d13830eff" +rustbn.js@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" + integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== rx-lite-aggregates@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= dependencies: rx-lite "*" rx-lite@*, rx-lite@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= -safe-buffer@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-event-emitter@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" + integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== + dependencies: + events "^3.0.0" safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" safe@^0.4.5: version "0.4.6" resolved "https://registry.yarnpkg.com/safe/-/safe-0.4.6.tgz#1d5580cf2635c5cb940ea48fb5081ae3c25b1be1" + integrity sha1-HVWAzyY1xcuUDqSPtQga48JbG+E= safefs@^3.1.2: version "3.2.2" resolved "https://registry.yarnpkg.com/safefs/-/safefs-3.2.2.tgz#8170c1444d7038e08caea05a374fae2fa349e15c" + integrity sha1-gXDBRE1wOOCMrqBaN0+uL6NJ4Vw= dependencies: graceful-fs "*" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== scandirectory@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/scandirectory/-/scandirectory-2.5.0.tgz#6ce03f54a090b668e3cbedbf20edf9e310593e72" + integrity sha1-bOA/VKCQtmjjy+2/IO354xBZPnI= dependencies: ignorefs "^1.0.0" safefs "^3.1.2" taskgroup "^4.0.5" +schedule@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" + integrity sha512-HUcJicG5Ou8xfR//c2rPT0lPIRR09vVvN81T9fqfVgBmhERUbDEQoYKjpBxbueJnCPpSu2ujXzOnRQt6x9o/jw== + dependencies: + object-assign "^4.1.1" + scrypt-async@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/scrypt-async/-/scrypt-async-1.3.1.tgz#a11fd6fac981b4b823ee01dee0221169500ddae9" + integrity sha1-oR/W+smBtLgj7gHe4CIRaVAN2uk= scrypt-js@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" + integrity sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q= scrypt.js@0.2.0, scrypt.js@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.2.0.tgz#af8d1465b71e9990110bedfc593b9479e03a8ada" + integrity sha1-r40UZbcemZARC+38WTuUeeA6ito= dependencies: scrypt "^6.0.2" scryptsy "^1.2.1" @@ -5589,18 +6353,21 @@ scrypt.js@0.2.0, scrypt.js@^0.2.0: scrypt@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" + integrity sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0= dependencies: nan "^2.0.8" scryptsy@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" + integrity sha1-oyJfpLJST4AnAHYeKFW987LZIWM= dependencies: pbkdf2 "^3.0.3" secp256k1@^3.0.1: - version "3.5.0" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.0.tgz#677d3b8a8e04e1a5fa381a1ae437c54207b738d0" + version "3.5.2" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.2.tgz#f95f952057310722184fe9c914e6b71281f2f2ae" + integrity sha512-iin3kojdybY6NArd+UFsoTuapOF7bnJNf2UbcWXaY3z+E1sJDipl60vtzB5hbO/uquBu7z0fd4VC4Irp+xoFVQ== dependencies: bindings "^1.2.1" bip66 "^1.1.3" @@ -5614,24 +6381,29 @@ secp256k1@^3.0.1: seek-bzip@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= dependencies: commander "~2.8.1" semaphore@>=1.0.1, semaphore@^1.0.3: version "1.1.0" resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" + integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== semver@~5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== dependencies: debug "2.6.9" depd "~1.1.2" @@ -5650,6 +6422,7 @@ send@0.16.2: serve-static@1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" @@ -5659,6 +6432,7 @@ serve-static@1.13.2: servify@^0.1.12: version "0.1.12" resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== dependencies: body-parser "^1.16.0" cors "^2.8.1" @@ -5669,14 +6443,17 @@ servify@^0.1.12: set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= set-value@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -5686,6 +6463,7 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -5695,22 +6473,22 @@ set-value@^2.0.0: setimmediate@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" + integrity sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48= setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - -setprototypeof@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -5718,22 +6496,26 @@ sha.js@^2.4.0, sha.js@^2.4.8: sha3@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.2.tgz#a66c5098de4c25bc88336ec8b4817d005bca7ba9" + integrity sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k= dependencies: nan "2.10.0" shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= shelljs@^0.7.4: version "0.7.8" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + integrity sha1-3svPh0sNHl+3LhSxZKloMEjprLM= dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -5742,6 +6524,7 @@ shelljs@^0.7.4: shelljs@^0.8.1, shelljs@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.2.tgz#345b7df7763f4c2340d584abb532c5f752ca9e35" + integrity sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ== dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -5750,14 +6533,17 @@ shelljs@^0.8.1, shelljs@^0.8.2: signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= simple-concat@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= simple-get@^2.7.0: version "2.8.1" resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" + integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== dependencies: decompress-response "^3.3.0" once "^1.3.1" @@ -5766,16 +6552,19 @@ simple-get@^2.7.0: slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= slice-ansi@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== dependencies: is-fullwidth-code-point "^2.0.0" snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" isobject "^3.0.0" @@ -5784,12 +6573,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" debug "^2.2.0" @@ -5800,27 +6591,25 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - sol-digger@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/sol-digger/-/sol-digger-0.0.2.tgz#406c4a9d31e269e7f88eb1c2ea101318e5e09025" + integrity sha1-QGxKnTHiaef4jrHC6hATGOXgkCU= sol-explore@1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/sol-explore/-/sol-explore-1.6.1.tgz#b59f073c69fe332560d5a10c32ba8ca7f2986cfb" + integrity sha1-tZ8HPGn+MyVg1aEMMrqMp/KYbPs= sol-explore@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/sol-explore/-/sol-explore-1.6.2.tgz#43ae8c419fd3ac056a05f8a9d1fb1022cd41ecc2" + integrity sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI= sol-merger@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/sol-merger/-/sol-merger-0.1.2.tgz#1f12500f42d427dc0ec8e4c113392acd8a6f62d9" + integrity sha512-12Z84jxeb5VFlQOGS38HOiTrHYohU07oQ5wHOcFJmcRRbaL5kWN7IcldMO1QdW8kONyKdj0xhukzLlN5m5ix4w== dependencies: bluebird "^3.5.0" cli-color "^1.2.0" @@ -5829,9 +6618,10 @@ sol-merger@^0.1.2: fs-extra "^4.0.2" glob "^7.1.2" -solc@0.4.24, solc@^0.4.19, solc@^0.4.24: +solc@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.24.tgz#354f14b269b38cbaa82a47d1ff151723502b954e" + integrity sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ== dependencies: fs-extra "^0.30.0" memorystream "^0.3.1" @@ -5839,9 +6629,10 @@ solc@0.4.24, solc@^0.4.19, solc@^0.4.24: semver "^5.3.0" yargs "^4.7.1" -solc@^0.4.2: - version "0.4.23" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.23.tgz#54a0ff4015827b32fddb62c0a418b5247310a58e" +solc@^0.4.19, solc@^0.4.2, solc@^0.4.24: + version "0.4.25" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.25.tgz#06b8321f7112d95b4b903639b1138a4d292f5faa" + integrity sha512-jU1YygRVy6zatgXrLY2rRm7HW1d7a8CkkEgNJwvH2VLpWhMFsMdWcJn6kUqZwcSz/Vm+w89dy7Z/aB5p6AFTrg== dependencies: fs-extra "^0.30.0" memorystream "^0.3.1" @@ -5849,9 +6640,10 @@ solc@^0.4.2: semver "^5.3.0" yargs "^4.7.1" -solidity-coverage@^0.5.10: +solidity-coverage@^0.5.11: version "0.5.11" resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.5.11.tgz#1ee45f6d98b75a615aadb8f9aa7db4a2b32258e7" + integrity sha512-qikdsSi6+9XbfvwA0aI7HUVpF9fIFNqRWTw23M89GMDY+b6Gj0wWU9IngJS0fimoZIAdEp3bfChxvpfVcrUesg== dependencies: death "^1.1.0" ethereumjs-testrpc-sc "6.1.6" @@ -5867,6 +6659,7 @@ solidity-coverage@^0.5.10: solidity-docgen@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.1.0.tgz#f3a56ff074e8c7d832af3a3d462c3b5abf0f64cb" + integrity sha512-F7ufNWmlP5c5hIi66Ijv9tc+HNosyO7ijWq6pRtyBR1WqyJBH/0DJkD6QZI8HkE8p6LEXiPKxGBWbAeVT9Nu9g== dependencies: commander "^2.14.1" lodash "^4.17.5" @@ -5879,6 +6672,7 @@ solidity-docgen@^0.1.0: solidity-parser-sc@0.4.11: version "0.4.11" resolved "https://registry.yarnpkg.com/solidity-parser-sc/-/solidity-parser-sc-0.4.11.tgz#86734c9205537007f4d6201b57176e41696ee607" + integrity sha512-1kV5iC7m3CtMDfmHaVNwz2saSGQVIuF16rIxU417Al38MVCWHMQQ5vT6cmLsNwDe60S74auobWij9vNawSeOyw== dependencies: mocha "^4.1.0" pegjs "^0.10.0" @@ -5887,15 +6681,18 @@ solidity-parser-sc@0.4.11: solium-plugin-security@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/solium-plugin-security/-/solium-plugin-security-0.1.1.tgz#2a87bcf8f8c3abf7d198e292e4ac080284e3f3f6" + integrity sha512-kpLirBwIq4mhxk0Y/nn5cQ6qdJTI+U1LO3gpoNIcqNaW+sI058moXBe2UiHs+9wvF9IzYD49jcKhFTxcR9u9SQ== solium@^1.1.6: - version "1.1.7" - resolved "https://registry.yarnpkg.com/solium/-/solium-1.1.7.tgz#332e499be0dbcac663af886de82ff1ed7e3d51af" + version "1.1.8" + resolved "https://registry.yarnpkg.com/solium/-/solium-1.1.8.tgz#35d30a15c572a233ce8a90226d6cfccb762fadb7" + integrity sha512-fn0lusM6of14CytIDDHK73SGjn6NsVTaCVJjaKCKJyqKhT00rH/hDtvnIeZ2ZTD9z/xaXd4Js2brW3az6AV9RA== dependencies: ajv "^5.2.2" chokidar "^1.6.0" colors "^1.1.2" commander "^2.9.0" + eol "^0.9.1" js-string-escape "^1.0.1" lodash "^4.14.2" sol-digger "0.0.2" @@ -5907,6 +6704,7 @@ solium@^1.1.6: solparse@2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/solparse/-/solparse-2.2.5.tgz#72709c867cd6bfc50ec2325f4b81d2b3ea365d99" + integrity sha512-t7tvtR6KU6QfPYLMv1nlCh9DA8HYIu5tbjHpKu0fhGFZ1NuSp0KKDHfFHv07g6v1xgcuUY3rVqNFjZt5b9+5qA== dependencies: mocha "^4.0.1" pegjs "^0.10.0" @@ -5915,14 +6713,17 @@ solparse@2.2.5: sorted-array-functions@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/sorted-array-functions/-/sorted-array-functions-1.2.0.tgz#43265b21d6e985b7df31621b1c11cc68d8efc7c3" + integrity sha512-sWpjPhIZJtqO77GN+LD8dDsDKcWZ9GCOJNqKzi1tvtjGIzwfoyuRH8S0psunmc6Z5P+qfDqztSbwYR5X/e1UTg== source-list-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-resolve@^0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== dependencies: atob "^2.1.1" decode-uri-component "^0.2.0" @@ -5933,12 +6734,14 @@ source-map-resolve@^0.5.0: source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== dependencies: source-map "^0.5.6" source-map-support@^0.5.3: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -5946,114 +6749,128 @@ source-map-support@^0.5.3: source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= dependencies: amdefine ">=0.0.4" spdx-correct@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" + integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== spdx-expression-parse@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz#e2a303236cac54b04031fa7a5a79c7e701df852f" + integrity sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@>=1.0.3: version "1.1.1" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" + integrity sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw= sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.1.tgz#130f5975eddad963f1d56f92b9ac6c51fa9f83eb" + version "1.15.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.1.tgz#b79a089a732e346c6e0714830f36285cd38191a2" + integrity sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" ecc-jsbn "~0.1.1" + getpass "^0.1.1" jsbn "~0.1.0" + safer-buffer "^2.0.2" tweetnacl "~0.14.0" stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2": +"statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== stdio@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/stdio/-/stdio-0.2.7.tgz#a1c57da10fe1cfaa0c3bf683c9d0743d1b660839" + integrity sha1-ocV9oQ/hz6oMO/aDydB0PRtmCDk= stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= dependencies: inherits "~2.0.1" readable-stream "^2.0.2" stream-http@^2.7.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.2.tgz#4126e8c6b107004465918aa2fc35549e77402c87" + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" @@ -6064,27 +6881,31 @@ stream-http@^2.7.2: strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= string-extended@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/string-extended/-/string-extended-0.0.8.tgz#741957dff487b0272a79eec5a44f239ee6f17ccd" + integrity sha1-dBlX3/SHsCcqee7FpE8jnubxfM0= dependencies: array-extended "~0.0.5" date-extended "~0.0.3" extended "~0.0.3" is-extended "~0.0.3" -string-width@^1.0.1, string-width@^1.0.2: +string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" @@ -6092,6 +6913,7 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: string.prototype.trim@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" + integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo= dependencies: define-properties "^1.1.2" es-abstract "^1.5.0" @@ -6100,90 +6922,109 @@ string.prototype.trim@~1.1.2: string_decoder@^1.0.0, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - -stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= dependencies: is-utf8 "^0.2.0" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= strip-dirs@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== dependencies: is-natural-number "^4.0.1" strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" + integrity sha1-DF8VX+8RUTczd96du1iNoFUA428= dependencies: is-hex-prefixed "1.0.0" strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= supports-color@4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + integrity sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ== dependencies: has-flag "^2.0.0" -supports-color@5.4.0, supports-color@^5.3.0: +supports-color@5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== dependencies: has-flag "^3.0.0" supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^3.1.0: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= dependencies: has-flag "^1.0.0" supports-color@^4.2.1: version "4.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + integrity sha1-vnoN5ITexcXN34s9WRJQRJEvY1s= dependencies: has-flag "^2.0.0" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + swarm-js@0.1.37: version "0.1.37" resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.37.tgz#27d485317a340bbeec40292af783cc10acfa4663" + integrity sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ== dependencies: bluebird "^3.5.0" buffer "^5.0.5" @@ -6202,6 +7043,7 @@ swarm-js@0.1.37: table@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA== dependencies: ajv "^5.2.3" ajv-keywords "^2.1.0" @@ -6213,40 +7055,44 @@ table@4.0.2: tapable@^0.2.7: version "0.2.8" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" + integrity sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI= tape@^4.4.0, tape@^4.6.3: - version "4.9.0" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.9.0.tgz#855c08360395133709d34d3fbf9ef341eb73ca6a" + version "4.9.1" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.9.1.tgz#1173d7337e040c76fbf42ec86fcabedc9b3805c9" + integrity sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw== dependencies: deep-equal "~1.0.1" defined "~1.0.0" - for-each "~0.3.2" + for-each "~0.3.3" function-bind "~1.1.1" glob "~7.1.2" - has "~1.0.1" + has "~1.0.3" inherits "~2.0.3" minimist "~1.2.0" - object-inspect "~1.5.0" - resolve "~1.5.0" + object-inspect "~1.6.0" + resolve "~1.7.1" resumer "~0.0.0" string.prototype.trim "~1.1.2" through "~2.3.8" tar-stream@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.0.tgz#a50efaa7b17760b82c27b3cae4a301a8254a5715" + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== dependencies: bl "^1.0.0" - buffer-alloc "^1.1.0" + buffer-alloc "^1.2.0" end-of-stream "^1.0.0" fs-constants "^1.0.0" - readable-stream "^2.0.0" - to-buffer "^1.1.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" xtend "^4.0.0" tar.gz@^1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/tar.gz/-/tar.gz-1.0.7.tgz#577ef2c595faaa73452ef0415fed41113212257b" + integrity sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg== dependencies: bluebird "^2.9.34" commander "^2.8.1" @@ -6257,18 +7103,20 @@ tar.gz@^1.0.5: tar@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= dependencies: block-stream "*" fstream "^1.0.2" inherits "2" tar@^4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.2.tgz#60685211ba46b38847b1ae7ee1a24d744a2cd462" + version "4.4.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" + integrity sha512-tMkTnh9EdzxyfW+6GK6fCahagXsnYk6kE6S9Gr9pjVdys769+laCTbodXDhPAjzVtEBazRgP0gYqOjnk9dQzLg== dependencies: chownr "^1.0.1" fs-minipass "^1.2.5" - minipass "^2.2.4" + minipass "^2.3.3" minizlib "^1.1.0" mkdirp "^0.5.0" safe-buffer "^5.1.2" @@ -6277,6 +7125,7 @@ tar@^4: taskgroup@^4.0.5, taskgroup@^4.2.0: version "4.3.1" resolved "https://registry.yarnpkg.com/taskgroup/-/taskgroup-4.3.1.tgz#7de193febd768273c457730497024d512c27915a" + integrity sha1-feGT/r12gnPEV3MElwJNUSwnkVo= dependencies: ambi "^2.2.0" csextends "^1.0.3" @@ -6284,43 +7133,51 @@ taskgroup@^4.0.5, taskgroup@^4.2.0: text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= thenify-all@^1.0.0, thenify-all@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= dependencies: thenify ">= 3.1.0 < 4" "thenify@>= 3.1.0 < 4": version "3.3.0" resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= dependencies: any-promise "^1.0.0" through@^2.3.6, through@~2.3.4, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= timers-browserify@^2.0.4: version "2.0.10" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== dependencies: setimmediate "^1.0.4" -timers-ext@0.1, timers-ext@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.2.tgz#61cc47a76c1abd3195f14527f978d58ae94c5204" +timers-ext@^0.1.5: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== dependencies: - es5-ext "~0.10.14" + es5-ext "~0.10.46" next-tick "1" tingodb@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/tingodb/-/tingodb-0.6.1.tgz#f63336259af7dfa6c90dfe2556a0dfb0d4eede59" + integrity sha1-9jM2JZr336bJDf4lVqDfsNTu3lk= dependencies: lodash "^4.17.5" safe "^0.4.5" @@ -6331,30 +7188,36 @@ tingodb@^0.6.1: tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= -to-buffer@^1.1.0: +to-buffer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -6362,6 +7225,7 @@ to-regex-range@^2.1.0: to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" extend-shallow "^3.0.2" @@ -6371,57 +7235,60 @@ to-regex@^3.0.1, to-regex@^3.0.2: tough-cookie@>=2.3.3, tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== dependencies: psl "^1.1.24" punycode "^1.4.1" -tough-cookie@~2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - dependencies: - punycode "^1.4.1" - tree-kill@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.0.tgz#5846786237b4239014f05db156b643212d4c6f36" + integrity sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg== trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= trim@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= -truffle-blockchain-utils@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.4.tgz#e31a346db61775c80ccd6f632de5e72f97f20ea5" +truffle-blockchain-utils@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.5.tgz#a4e5c064dadd69f782a137f3d276d21095da7a47" + integrity sha1-pOXAZNrdafeCoTfz0nbSEJXaekc= -truffle-contract-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/truffle-contract-schema/-/truffle-contract-schema-2.0.0.tgz#535378c0b6a7f58011ea8d84f57771771cb45163" +truffle-contract-schema@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/truffle-contract-schema/-/truffle-contract-schema-2.0.1.tgz#9bf821d32e26e674ba15eb5d40f96b10b1c9d568" + integrity sha1-m/gh0y4m5nS6FetdQPlrELHJ1Wg= dependencies: ajv "^5.1.1" crypto-js "^3.1.9-1" debug "^3.1.0" truffle-contract@^3.0.4: - version "3.0.5" - resolved "https://registry.yarnpkg.com/truffle-contract/-/truffle-contract-3.0.5.tgz#c25d07042dcd519413bfee21034ed6ee7fc373bf" + version "3.0.6" + resolved "https://registry.yarnpkg.com/truffle-contract/-/truffle-contract-3.0.6.tgz#2ef6fc32d7faafa9f4aed8e50001a9fdea342192" + integrity sha1-Lvb8Mtf6r6n0rtjlAAGp/eo0IZI= dependencies: ethjs-abi "0.1.8" - truffle-blockchain-utils "^0.0.4" - truffle-contract-schema "^2.0.0" - truffle-error "0.0.2" - web3 "^0.20.1" + truffle-blockchain-utils "^0.0.5" + truffle-contract-schema "^2.0.1" + truffle-error "^0.0.3" + web3 "0.20.6" -truffle-error@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/truffle-error/-/truffle-error-0.0.2.tgz#01b189b78505566ae1689c239c7ca2dd121cfe4c" +truffle-error@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/truffle-error/-/truffle-error-0.0.3.tgz#4bf55242e14deee1c7194932709182deff2c97ca" + integrity sha1-S/VSQuFN7uHHGUkycJGC3v8sl8o= truffle-hdwallet-provider-privkey@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/truffle-hdwallet-provider-privkey/-/truffle-hdwallet-provider-privkey-0.1.0.tgz#9417047a74ad37d923df926154b6486ffb57f6c9" + integrity sha512-Vj04yr2d9qLRZspoHztbE/YQnVaoFb90JNZHtggRUm+JFm/NOiSJHLVI63+3mtUIuQ04EuKZ7Df8JQw0Ni7IeA== dependencies: ethereumjs-tx "^1.3.3" ethereumjs-wallet "^0.6.0" @@ -6431,6 +7298,7 @@ truffle-hdwallet-provider-privkey@^0.1.0: truffle-wallet-provider@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/truffle-wallet-provider/-/truffle-wallet-provider-0.0.5.tgz#db59ce6fa1c558766011137509a94dfca8d1408e" + integrity sha1-21nOb6HFWHZgERN1CalN/KjRQI4= dependencies: ethereumjs-wallet "^0.6.0" web3 "^0.18.2" @@ -6439,6 +7307,7 @@ truffle-wallet-provider@0.0.5: truffle@^4.1.13: version "4.1.14" resolved "https://registry.yarnpkg.com/truffle/-/truffle-4.1.14.tgz#8d2c298e29abf9b1e486e44ff9faca6d34bb9030" + integrity sha512-e7tTLvKP3bN9dE7MagfWyFjy4ZgoEGbeujECy1me1ENBzbj/aO/+45gs72qsL3+3IkCNNcWNOJjjrm8BYZZNNg== dependencies: mocha "^4.1.0" original-require "1.0.1" @@ -6447,30 +7316,36 @@ truffle@^4.1.13: tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= dependencies: safe-buffer "^5.0.1" tweetnacl@0.13.2: version "0.13.2" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.13.2.tgz#453161770469d45cd266c36404e2bc99a8fa9944" + integrity sha1-RTFhdwRp1FzSZsNkBOK8maj6mUQ= tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= dependencies: prelude-ls "~1.1.2" -type-is@~1.6.15, type-is@~1.6.16: +type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== dependencies: media-typer "0.3.0" mime-types "~2.1.18" @@ -6478,47 +7353,59 @@ type-is@~1.6.15, type-is@~1.6.16: typechecker@^2.0.8: version "2.1.0" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-2.1.0.tgz#d1c2093a54ff8a19f58cff877eeaa54f2242d383" + integrity sha1-0cIJOlT/ihn1jP+HfuqlTyJC04M= typechecker@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.5.0.tgz#c382920097812364bbaf4595b0ab6588244117a6" + version "4.6.0" + resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.6.0.tgz#d245d9c2df21147d5e2a942fff170b68ece73c87" + integrity sha512-83OrXpyP3LNr7aRbLkt2nkjE/d7q8su8/uRvrKxCpswqVCVGOgyaKpaz8/MTjQqBYe4eLNuJ44pNakFZKqyPMA== dependencies: - editions "^1.3.4" + editions "^2.0.2" typechecker@~2.0.1: version "2.0.8" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-2.0.8.tgz#e83da84bb64c584ccb345838576c40b0337db82e" + integrity sha1-6D2oS7ZMWEzLNFg4V2xAsDN9uC4= typedarray-to-buffer@^3.1.2: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== dependencies: is-typedarray "^1.0.0" typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -ua-parser-js@^0.7.18: - version "0.7.18" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed" - -uglify-js@^2.6, uglify-js@^2.8.29: +uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= dependencies: source-map "~0.5.1" yargs "~3.10.0" optionalDependencies: uglify-to-browserify "~1.0.0" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= uglifyjs-webpack-plugin@^0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" + integrity sha1-uVH0q7a9YX5m9j64kUmOORdj4wk= dependencies: source-map "^0.5.6" uglify-js "^2.8.29" @@ -6527,10 +7414,12 @@ uglifyjs-webpack-plugin@^0.4.6: ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== unbzip2-stream@^1.0.9: - version "1.2.5" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz#73a033a567bbbde59654b193c44d48a7e4f43c47" + version "1.3.1" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz#7854da51622a7e63624221196357803b552966a1" + integrity sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw== dependencies: buffer "^3.0.1" through "^2.3.6" @@ -6538,14 +7427,17 @@ unbzip2-stream@^1.0.9: underscore@1.8.3: version "1.8.3" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI= underscore@^1.8.3: version "1.9.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" get-value "^2.0.6" @@ -6553,110 +7445,133 @@ union-value@^1.0.0: set-value "^0.4.3" universalify@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== unorm@^1.3.3: version "1.4.1" resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300" + integrity sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA= unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" isobject "^3.0.0" -upath@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.5.tgz#02cab9ecebe95bbec6d5fc2566325725ab6d1a73" +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== -uri-js@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.1.tgz#4595a80a51f356164e22970df64c7abd6ade9850" +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= dependencies: prepend-http "^1.0.1" url-set-query@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk= url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= dependencies: punycode "1.3.2" querystring "0.2.0" use@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" - dependencies: - kind-of "^6.0.2" + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== utf8@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.1.tgz#2e01db02f7d8d0944f77104f1609eb0c304cf768" + integrity sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g= utf8@^2.1.1, utf8@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" + integrity sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY= + +utf8@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util@0.10.3, util@^0.10.3: +util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: inherits "2.0.1" +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= uuid@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - -uuid@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= uuid@^3.0.1, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - -uuid@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== valid-url@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= validate-npm-package-license@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" @@ -6664,14 +7579,17 @@ validate-npm-package-license@^3.0.1: varint@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.0.tgz#d826b89f7490732fabc0c0ed693ed475dcb29ebf" + integrity sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8= vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" @@ -6680,12 +7598,14 @@ verror@1.10.0: vm-browserify@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= dependencies: indexof "0.0.1" watchpack@^1.4.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== dependencies: chokidar "^2.0.2" graceful-fs "^4.1.2" @@ -6694,6 +7614,7 @@ watchpack@^1.4.0: watchr@~2.4.13: version "2.4.13" resolved "https://registry.yarnpkg.com/watchr/-/watchr-2.4.13.tgz#d74847bb4d6f90f61fe2c74f9f68662aa0e07601" + integrity sha1-10hHu01vkPYf4sdPn2hmKqDgdgE= dependencies: eachr "^2.0.2" extendr "^2.1.0" @@ -6707,6 +7628,7 @@ watchr@~2.4.13: web3-bzz@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.0.0-beta.34.tgz#068d37777ab65e5c60f8ec8b9a50cfe45277929c" + integrity sha1-Bo03d3q2Xlxg+OyLmlDP5FJ3kpw= dependencies: got "7.1.0" swarm-js "0.1.37" @@ -6715,6 +7637,7 @@ web3-bzz@1.0.0-beta.34: web3-core-helpers@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.34.tgz#b168da00d3e19e156bc15ae203203dd4dfee2d03" + integrity sha1-sWjaANPhnhVrwVriAyA91N/uLQM= dependencies: underscore "1.8.3" web3-eth-iban "1.0.0-beta.34" @@ -6723,6 +7646,7 @@ web3-core-helpers@1.0.0-beta.34: web3-core-method@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.34.tgz#ec163c8a2c490fa02a7ec15559fa7307fc7cc6dd" + integrity sha1-7BY8iixJD6AqfsFVWfpzB/x8xt0= dependencies: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" @@ -6733,6 +7657,7 @@ web3-core-method@1.0.0-beta.34: web3-core-promievent@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.34.tgz#a4f4fa6784bb293e82c60960ae5b56a94cd03edc" + integrity sha1-pPT6Z4S7KT6CxglgrltWqUzQPtw= dependencies: any-promise "1.3.0" eventemitter3 "1.1.1" @@ -6740,6 +7665,7 @@ web3-core-promievent@1.0.0-beta.34: web3-core-requestmanager@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.34.tgz#01f8f6cf2ae6b6f0b70c38bae1ef741b5bab215c" + integrity sha1-Afj2zyrmtvC3DDi64e90G1urIVw= dependencies: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" @@ -6750,6 +7676,7 @@ web3-core-requestmanager@1.0.0-beta.34: web3-core-subscriptions@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.34.tgz#9fed144033f221c3cf21060302ffdaf5ef2de2de" + integrity sha1-n+0UQDPyIcPPIQYDAv/a9e8t4t4= dependencies: eventemitter3 "1.1.1" underscore "1.8.3" @@ -6758,6 +7685,7 @@ web3-core-subscriptions@1.0.0-beta.34: web3-core@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.34.tgz#121be8555e9fb00d2c5d05ddd3381d0c9e46987e" + integrity sha1-EhvoVV6fsA0sXQXd0zgdDJ5GmH4= dependencies: web3-core-helpers "1.0.0-beta.34" web3-core-method "1.0.0-beta.34" @@ -6767,6 +7695,7 @@ web3-core@1.0.0-beta.34: web3-eth-abi@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.34.tgz#034533e3aa2f7e59ff31793eaea685c0ed5af67a" + integrity sha1-A0Uz46ovfln/MXk+rqaFwO1a9no= dependencies: bn.js "4.11.6" underscore "1.8.3" @@ -6776,6 +7705,7 @@ web3-eth-abi@1.0.0-beta.34: web3-eth-accounts@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.34.tgz#e09142eeecc797ac3459b75e9b23946d3695f333" + integrity sha1-4JFC7uzHl6w0WbdemyOUbTaV8zM= dependencies: any-promise "1.3.0" crypto-browserify "3.12.0" @@ -6791,6 +7721,7 @@ web3-eth-accounts@1.0.0-beta.34: web3-eth-contract@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.34.tgz#9dbb38fae7643a808427a20180470ec7415c91e6" + integrity sha1-nbs4+udkOoCEJ6IBgEcOx0FckeY= dependencies: underscore "1.8.3" web3-core "1.0.0-beta.34" @@ -6804,6 +7735,7 @@ web3-eth-contract@1.0.0-beta.34: web3-eth-iban@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.34.tgz#9af458605867ccf74ea979aaf326b38ba6a5ba0c" + integrity sha1-mvRYYFhnzPdOqXmq8yazi6alugw= dependencies: bn.js "4.11.6" web3-utils "1.0.0-beta.34" @@ -6811,6 +7743,7 @@ web3-eth-iban@1.0.0-beta.34: web3-eth-personal@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.34.tgz#9afba167342ebde5420bcd5895c3f6c34388f205" + integrity sha1-mvuhZzQuveVCC81YlcP2w0OI8gU= dependencies: web3-core "1.0.0-beta.34" web3-core-helpers "1.0.0-beta.34" @@ -6821,6 +7754,7 @@ web3-eth-personal@1.0.0-beta.34: web3-eth@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.34.tgz#74086000850c6fe6f535ef49837d6d4bb6113268" + integrity sha1-dAhgAIUMb+b1Ne9Jg31tS7YRMmg= dependencies: underscore "1.8.3" web3-core "1.0.0-beta.34" @@ -6838,6 +7772,7 @@ web3-eth@1.0.0-beta.34: web3-net@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.34.tgz#427cea2f431881449c8e38d523290f173f9ff63d" + integrity sha1-QnzqL0MYgUScjjjVIykPFz+f9j0= dependencies: web3-core "1.0.0-beta.34" web3-core-method "1.0.0-beta.34" @@ -6846,6 +7781,7 @@ web3-net@1.0.0-beta.34: web3-provider-engine@^13.6.4: version "13.8.0" resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz#4c7c1ad2af5f1fe10343b8a65495879a2f9c00df" + integrity sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ== dependencies: async "^2.5.0" clone "^2.0.0" @@ -6870,6 +7806,7 @@ web3-provider-engine@^13.6.4: web3-provider-engine@^8.4.0: version "8.6.1" resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-8.6.1.tgz#4d86e19e30caaf97df351511ec0f60136e5b30eb" + integrity sha1-TYbhnjDKr5ffNRUR7A9gE25bMOs= dependencies: async "^2.1.2" clone "^2.0.0" @@ -6889,6 +7826,7 @@ web3-provider-engine@^8.4.0: web3-providers-http@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.34.tgz#e561b52bbb43766282007d40285bfe3550c27e7a" + integrity sha1-5WG1K7tDdmKCAH1AKFv+NVDCfno= dependencies: web3-core-helpers "1.0.0-beta.34" xhr2 "0.1.4" @@ -6896,6 +7834,7 @@ web3-providers-http@1.0.0-beta.34: web3-providers-ipc@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.34.tgz#a1b77f1a306d73649a9c039052e40cb71328d00a" + integrity sha1-obd/GjBtc2SanAOQUuQMtxMo0Ao= dependencies: oboe "2.1.3" underscore "1.8.3" @@ -6904,6 +7843,7 @@ web3-providers-ipc@1.0.0-beta.34: web3-providers-ws@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.34.tgz#7de70f1b83f2de36476772156becfef6e3516eb3" + integrity sha1-fecPG4Py3jZHZ3IVa+z+9uNRbrM= dependencies: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" @@ -6912,6 +7852,7 @@ web3-providers-ws@1.0.0-beta.34: web3-shh@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.34.tgz#975061d71eaec42ccee576f7bd8f70f03844afe0" + integrity sha1-l1Bh1x6uxCzO5Xb3vY9w8DhEr+A= dependencies: web3-core "1.0.0-beta.34" web3-core-method "1.0.0-beta.34" @@ -6921,6 +7862,7 @@ web3-shh@1.0.0-beta.34: web3-utils@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.34.tgz#9411fc39aaef39ca4e06169f762297d9ff020970" + integrity sha1-lBH8OarvOcpOBhafdiKX2f8CCXA= dependencies: bn.js "4.11.6" eth-lib "0.1.27" @@ -6933,6 +7875,7 @@ web3-utils@1.0.0-beta.34: web3@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/web3/-/web3-0.19.1.tgz#e763d5b1107c4bc24abd4f8cbee1ba3659e6eb31" + integrity sha1-52PVsRB8S8JKvU+MvuG6Nlnm6zE= dependencies: bignumber.js "^4.0.2" crypto-js "^3.1.4" @@ -6943,6 +7886,7 @@ web3@0.19.1: web3@0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.2.tgz#c54dac5fc0e377399c04c1a6ecbb12e4513278d6" + integrity sha1-xU2sX8DjdzmcBMGm7LsS5FEyeNY= dependencies: bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git" crypto-js "^3.1.4" @@ -6950,9 +7894,34 @@ web3@0.20.2: xhr2 "*" xmlhttprequest "*" +web3@0.20.6: + version "0.20.6" + resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.6.tgz#3e97306ae024fb24e10a3d75c884302562215120" + integrity sha1-PpcwauAk+yThCj11yIQwJWIhUSA= + dependencies: + bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git" + crypto-js "^3.1.4" + utf8 "^2.1.1" + xhr2 "*" + xmlhttprequest "*" + +web3@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.34.tgz#347e561b784098cb5563315f490479a1d91f2ab1" + integrity sha1-NH5WG3hAmMtVYzFfSQR5odkfKrE= + dependencies: + web3-bzz "1.0.0-beta.34" + web3-core "1.0.0-beta.34" + web3-eth "1.0.0-beta.34" + web3-eth-personal "1.0.0-beta.34" + web3-net "1.0.0-beta.34" + web3-shh "1.0.0-beta.34" + web3-utils "1.0.0-beta.34" + web3@^0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/web3/-/web3-0.16.0.tgz#a4554175cd462943035b1f1d39432f741c6b6019" + integrity sha1-pFVBdc1GKUMDWx8dOUMvdBxrYBk= dependencies: bignumber.js "git+https://github.com/debris/bignumber.js#master" crypto-js "^3.1.4" @@ -6962,6 +7931,7 @@ web3@^0.16.0: web3@^0.18.2, web3@^0.18.4: version "0.18.4" resolved "https://registry.yarnpkg.com/web3/-/web3-0.18.4.tgz#81ec1784145491f2eaa8955b31c06049e07c5e7d" + integrity sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0= dependencies: bignumber.js "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" crypto-js "^3.1.4" @@ -6969,31 +7939,21 @@ web3@^0.18.2, web3@^0.18.4: xhr2 "*" xmlhttprequest "*" -web3@^0.20.1, web3@^0.20.5: - version "0.20.6" - resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.6.tgz#3e97306ae024fb24e10a3d75c884302562215120" +web3@^0.20.5: + version "0.20.7" + resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.7.tgz#1605e6d81399ed6f85a471a4f3da0c8be57df2f7" + integrity sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ== dependencies: bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git" crypto-js "^3.1.4" utf8 "^2.1.1" - xhr2 "*" + xhr2-cookies "^1.1.0" xmlhttprequest "*" -web3@^1.0.0-beta.33: - version "1.0.0-beta.34" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.34.tgz#347e561b784098cb5563315f490479a1d91f2ab1" - dependencies: - web3-bzz "1.0.0-beta.34" - web3-core "1.0.0-beta.34" - web3-eth "1.0.0-beta.34" - web3-eth-personal "1.0.0-beta.34" - web3-net "1.0.0-beta.34" - web3-shh "1.0.0-beta.34" - web3-utils "1.0.0-beta.34" - webpack-sources@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== dependencies: source-list-map "^2.0.0" source-map "~0.6.1" @@ -7001,6 +7961,7 @@ webpack-sources@^1.0.1: webpack@^3.0.0: version "3.12.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.12.0.tgz#3f9e34360370602fcf639e97939db486f4ec0d74" + integrity sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ== dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" @@ -7035,40 +7996,48 @@ webpack@^3.0.0: yaeti "^0.0.6" whatwg-fetch@>=0.10.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= which@^1.1.1, which@^1.2.9: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: - string-width "^1.0.2" + string-width "^1.0.2 || 2" window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= window-size@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= winston@^2.3.1: - version "2.4.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.3.tgz#7a9fdab371b6d3d9b63a592947846d856948c517" + version "2.4.4" + resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.4.tgz#a01e4d1d0a103cf4eada6fc1f886b3110d71c34b" + integrity sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q== dependencies: async "~1.0.0" colors "1.0.x" @@ -7080,18 +8049,22 @@ winston@^2.3.1: wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -7099,16 +8072,19 @@ wrap-ansi@^2.0.0: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= dependencies: mkdirp "^0.5.1" ws@^3.0.0: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== dependencies: async-limiter "~1.0.0" safe-buffer "~5.1.0" @@ -7117,12 +8093,14 @@ ws@^3.0.0: xhr-request-promise@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz#343c44d1ee7726b8648069682d0f840c83b4261d" + integrity sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0= dependencies: xhr-request "^1.0.1" xhr-request@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== dependencies: buffer-to-arraybuffer "^0.0.5" object-assign "^4.1.1" @@ -7132,13 +8110,22 @@ xhr-request@^1.0.1: url-set-query "^1.0.0" xhr "^2.0.4" +xhr2-cookies@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= + dependencies: + cookiejar "^2.1.1" + xhr2@*, xhr2@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" + integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: - version "2.4.1" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.1.tgz#ba982cced205ae5eec387169ac9dc77ca4853d38" + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== dependencies: global "~4.3.0" is-function "^1.0.1" @@ -7148,40 +8135,49 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: xmlhttprequest@*, xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= xregexp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" + integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= xtend@~2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= dependencies: object-keys "~0.4.0" y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= yaeti@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= yargs-parser@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ= dependencies: camelcase "^3.0.0" lodash.assign "^4.0.6" @@ -7189,24 +8185,28 @@ yargs-parser@^2.4.1: yargs-parser@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= dependencies: camelcase "^4.1.0" yargs-parser@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" + integrity sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ== dependencies: camelcase "^4.1.0" yargs-parser@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= dependencies: camelcase "^4.1.0" yargs@^10.0.3: version "10.1.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" + integrity sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig== dependencies: cliui "^4.0.0" decamelize "^1.1.1" @@ -7224,6 +8224,7 @@ yargs@^10.0.3: yargs@^11.0.0: version "11.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== dependencies: cliui "^4.0.0" decamelize "^1.1.1" @@ -7241,6 +8242,7 @@ yargs@^11.0.0: yargs@^4.6.0, yargs@^4.7.1: version "4.8.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + integrity sha1-wMQpJMpKqmsObaFznfshZDn53cA= dependencies: cliui "^3.2.0" decamelize "^1.1.1" @@ -7260,6 +8262,7 @@ yargs@^4.6.0, yargs@^4.7.1: yargs@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= dependencies: camelcase "^4.1.0" cliui "^3.2.0" @@ -7278,6 +8281,7 @@ yargs@^8.0.2: yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= dependencies: camelcase "^1.0.2" cliui "^2.1.0" @@ -7285,8 +8289,9 @@ yargs@~3.10.0: window-size "0.1.0" yauzl@^2.4.2: - version "2.9.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= dependencies: buffer-crc32 "~0.2.3" - fd-slicer "~1.0.1" + fd-slicer "~1.1.0" From 05331d1f2fdfca50516b23c14620f7c7e1895b21 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Fri, 12 Oct 2018 15:58:28 -0300 Subject: [PATCH 134/142] linter errors and typos --- CLI/data/dividendsExclusions_data.csv | 1 + contracts/interfaces/IModuleFactory.sol | 2 +- contracts/mocks/MockFactory.sol | 2 +- contracts/mocks/TestSTOFactory.sol | 2 +- .../modules/Burn/TrackedRedemptionFactory.sol | 2 +- .../ERC20DividendCheckpointFactory.sol | 2 +- .../EtherDividendCheckpointFactory.sol | 2 +- contracts/modules/ModuleFactory.sol | 18 +- .../GeneralPermissionManagerFactory.sol | 2 +- contracts/modules/STO/CappedSTOFactory.sol | 2 +- contracts/modules/STO/DummySTOFactory.sol | 2 +- contracts/modules/STO/PreSaleSTOFactory.sol | 2 +- contracts/modules/STO/USDTieredSTOFactory.sol | 3 +- .../TransferManager/CountTransferManager.sol | 26 +-- .../CountTransferManagerFactory.sol | 6 +- .../GeneralTransferManager.sol | 34 +-- .../GeneralTransferManagerFactory.sol | 2 +- .../TransferManager/ITransferManager.sol | 4 +- .../LockupVolumeRestrictionTM.sol | 200 ++++++++++-------- .../LockupVolumeRestrictionTMFactory.sol | 2 +- .../ManualApprovalTransferManager.sol | 14 +- .../ManualApprovalTransferManagerFactory.sol | 2 +- .../PercentageTransferManager.sol | 6 +- .../PercentageTransferManagerFactory.sol | 4 +- .../SingleTradeVolumeRestrictionTM.sol | 33 +-- .../SingleTradeVolumeRestrictionTMFactory.sol | 2 +- 26 files changed, 211 insertions(+), 166 deletions(-) diff --git a/CLI/data/dividendsExclusions_data.csv b/CLI/data/dividendsExclusions_data.csv index bd8715437..406cd94cf 100644 --- a/CLI/data/dividendsExclusions_data.csv +++ b/CLI/data/dividendsExclusions_data.csv @@ -1,3 +1,4 @@ +0xee7ae74d964f2be7d72c1b187b38e2ed3615d4d1 0x49fc0b78238dab644698a90fa351b4c749e123d2 0x10223927009b8add0960359dd90d1449415b7ca9 0x3c65cfe3de848cf38e9d76e9c3e57a2f1140b399 diff --git a/contracts/interfaces/IModuleFactory.sol b/contracts/interfaces/IModuleFactory.sol index 839bb26ed..9cf834069 100644 --- a/contracts/interfaces/IModuleFactory.sol +++ b/contracts/interfaces/IModuleFactory.sol @@ -47,7 +47,7 @@ interface IModuleFactory { function getVersion() external view returns(string); /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns (string); diff --git a/contracts/mocks/MockFactory.sol b/contracts/mocks/MockFactory.sol index 144db6b15..5f2469cde 100644 --- a/contracts/mocks/MockFactory.sol +++ b/contracts/mocks/MockFactory.sol @@ -81,7 +81,7 @@ contract MockFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Mock Manager - This is mock in nature"; diff --git a/contracts/mocks/TestSTOFactory.sol b/contracts/mocks/TestSTOFactory.sol index 71517dcb8..85c32f2f9 100644 --- a/contracts/mocks/TestSTOFactory.sol +++ b/contracts/mocks/TestSTOFactory.sol @@ -82,7 +82,7 @@ contract TestSTOFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Test STO - you can mint tokens at will"; diff --git a/contracts/modules/Burn/TrackedRedemptionFactory.sol b/contracts/modules/Burn/TrackedRedemptionFactory.sol index c1a487e65..6b0761865 100644 --- a/contracts/modules/Burn/TrackedRedemptionFactory.sol +++ b/contracts/modules/Burn/TrackedRedemptionFactory.sol @@ -83,7 +83,7 @@ contract TrackedRedemptionFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Allows an investor to redeem security tokens which are tracked by this module"; diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol index 8d3644510..632bdee00 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpointFactory.sol @@ -83,7 +83,7 @@ contract ERC20DividendCheckpointFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created"; diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol index 487af022b..cebc79571 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpointFactory.sol @@ -83,7 +83,7 @@ contract EtherDividendCheckpointFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Create a dividend which will be paid out to token holders proportional to their balances at the point the dividend is created"; diff --git a/contracts/modules/ModuleFactory.sol b/contracts/modules/ModuleFactory.sol index 66ffc822d..a330bd0ea 100644 --- a/contracts/modules/ModuleFactory.sol +++ b/contracts/modules/ModuleFactory.sol @@ -20,7 +20,7 @@ contract ModuleFactory is IModuleFactory, Ownable { bytes32 public name; string public title; - // @notice Allow only two variables to store + // @notice Allow only two variables to be stored // 1. lowerBound // 2. upperBound // @dev (0.0.0 will act as the wildcard) @@ -38,10 +38,10 @@ contract ModuleFactory is IModuleFactory, Ownable { * @param _polyAddress Address of the polytoken */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public { - polyToken = IERC20(_polyAddress); - setupCost = _setupCost; - usageCost = _usageCost; - monthlySubscriptionCost = _subscriptionCost; + polyToken = IERC20(_polyAddress); + setupCost = _setupCost; + usageCost = _usageCost; + monthlySubscriptionCost = _subscriptionCost; } /** @@ -77,7 +77,7 @@ contract ModuleFactory is IModuleFactory, Ownable { * @param _newTitle New Title that will replace the old one. */ function changeTitle(string _newTitle) public onlyOwner { - require(bytes(_newTitle).length > 0); + require(bytes(_newTitle).length > 0, "Invalid title"); title = _newTitle; } @@ -86,7 +86,7 @@ contract ModuleFactory is IModuleFactory, Ownable { * @param _newDesc New description that will replace the old one. */ function changeDescription(string _newDesc) public onlyOwner { - require(bytes(_newDesc).length > 0); + require(bytes(_newDesc).length > 0, "Invalid description"); description = _newDesc; } @@ -95,7 +95,7 @@ contract ModuleFactory is IModuleFactory, Ownable { * @param _newName New name that will replace the old one. */ function changeName(bytes32 _newName) public onlyOwner { - require(_newName != bytes32(0)); + require(_newName != bytes32(0),"Invalid name"); name = _newName; } @@ -104,7 +104,7 @@ contract ModuleFactory is IModuleFactory, Ownable { * @param _newVersion New name that will replace the old one. */ function changeVersion(string _newVersion) public onlyOwner { - require(bytes(_newVersion).length > 0 ); + require(bytes(_newVersion).length > 0, "Invalid version"); version = _newVersion; } diff --git a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol index 078f408dc..7988cc4d7 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol @@ -80,7 +80,7 @@ contract GeneralPermissionManagerFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Add and remove permissions for the SecurityToken and associated modules. Permission types should be encoded as bytes32 values, and attached using the withPerm modifier to relevant functions.No initFunction required."; diff --git a/contracts/modules/STO/CappedSTOFactory.sol b/contracts/modules/STO/CappedSTOFactory.sol index 3c3597957..2c17bb299 100644 --- a/contracts/modules/STO/CappedSTOFactory.sol +++ b/contracts/modules/STO/CappedSTOFactory.sol @@ -85,7 +85,7 @@ contract CappedSTOFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Initialises a capped STO. Init parameters are _startTime (time STO starts), _endTime (time STO ends), _cap (cap in tokens for STO), _rate (POLY/ETH to token rate), _fundRaiseType (whether you are raising in POLY or ETH), _polyToken (address of POLY token), _fundsReceiver (address which will receive funds)"; diff --git a/contracts/modules/STO/DummySTOFactory.sol b/contracts/modules/STO/DummySTOFactory.sol index e4ddb8136..94aa9516b 100644 --- a/contracts/modules/STO/DummySTOFactory.sol +++ b/contracts/modules/STO/DummySTOFactory.sol @@ -84,7 +84,7 @@ contract DummySTOFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Dummy STO - you can mint tokens at will"; diff --git a/contracts/modules/STO/PreSaleSTOFactory.sol b/contracts/modules/STO/PreSaleSTOFactory.sol index a939fce19..b4faf07a9 100644 --- a/contracts/modules/STO/PreSaleSTOFactory.sol +++ b/contracts/modules/STO/PreSaleSTOFactory.sol @@ -87,7 +87,7 @@ contract PreSaleSTOFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Configure and track pre-sale token allocations"; diff --git a/contracts/modules/STO/USDTieredSTOFactory.sol b/contracts/modules/STO/USDTieredSTOFactory.sol index e5a459f73..4c4274ff8 100644 --- a/contracts/modules/STO/USDTieredSTOFactory.sol +++ b/contracts/modules/STO/USDTieredSTOFactory.sol @@ -43,7 +43,6 @@ contract USDTieredSTOFactory is ModuleFactory { require(address(usdTieredSTO).call(_data), "Unsuccessfull call"); emit GenerateModuleFromFactory(usdTieredSTO, getName(), address(this), msg.sender, setupCost, now); return address(usdTieredSTO); - // return 0xca35b7d915458ef540ade6068dfe2f44e8fa733c; } /** @@ -91,7 +90,7 @@ contract USDTieredSTOFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Initialises a USD tiered STO."; diff --git a/contracts/modules/TransferManager/CountTransferManager.sol b/contracts/modules/TransferManager/CountTransferManager.sol index 32df49dd4..7d8edaf58 100644 --- a/contracts/modules/TransferManager/CountTransferManager.sol +++ b/contracts/modules/TransferManager/CountTransferManager.sol @@ -25,7 +25,9 @@ contract CountTransferManager is ITransferManager { { } - /// @notice Used to verify the transfer transaction according to the rule implemented in the trnasfer managers + /** @notice Used to verify the transfer transaction and prevent a transfer if it passes the allowed amount of token holders + * @param _to Address of the receiver + */ function verifyTransfer(address /* _from */, address _to, uint256 /* _amount */, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { if (!paused) { if (maxHolderCount < ISecurityToken(securityToken).getInvestorCount()) { @@ -41,29 +43,29 @@ contract CountTransferManager is ITransferManager { } /** - * @notice Used to intialize the variables of the contract - * @param _maxHolderCount Maximum no. of holders for the securityToken + * @notice Used to initialize the variables of the contract + * @param _maxHolderCount Maximum no. of holders this module allows the SecurityToken to have */ function configure(uint256 _maxHolderCount) public onlyFactory { maxHolderCount = _maxHolderCount; } /** - * @notice This function returns the signature of configure function - */ - function getInitFunction() public pure returns (bytes4) { - return bytes4(keccak256("configure(uint256)")); - } - - /** - * @notice sets the maximum percentage that an individual token holder can hold - * @param _maxHolderCount is the new maximum amount a holder can hold + * @notice sets the cap for the amount of token holders there can be + * @param _maxHolderCount is the new maximum amount of token holders */ function changeHolderCount(uint256 _maxHolderCount) public withPerm(ADMIN) { emit ModifyHolderCount(maxHolderCount, _maxHolderCount); maxHolderCount = _maxHolderCount; } + /** + * @notice This function returns the signature of configure function + */ + function getInitFunction() public pure returns (bytes4) { + return bytes4(keccak256("configure(uint256)")); + } + /** * @notice Return the permissions flag that are associated with CountTransferManager */ diff --git a/contracts/modules/TransferManager/CountTransferManagerFactory.sol b/contracts/modules/TransferManager/CountTransferManagerFactory.sol index 1fe47a853..7469667bb 100644 --- a/contracts/modules/TransferManager/CountTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/CountTransferManagerFactory.sol @@ -34,7 +34,7 @@ contract CountTransferManagerFactory is ModuleFactory { require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); CountTransferManager countTransferManager = new CountTransferManager(msg.sender, address(polyToken)); require(Util.getSig(_data) == countTransferManager.getInitFunction(), "Provided data is not valid"); - require(address(countTransferManager).call(_data), "Un-successfull call"); + require(address(countTransferManager).call(_data), "Unsuccessful call"); emit GenerateModuleFromFactory(address(countTransferManager), getName(), address(this), msg.sender, setupCost, now); return address(countTransferManager); @@ -85,7 +85,7 @@ contract CountTransferManagerFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Allows an issuer to restrict the total number of non-zero token holders"; @@ -95,7 +95,7 @@ contract CountTransferManagerFactory is ModuleFactory { * @notice Get the tags related to the module factory */ function getTags() external view returns(bytes32[]) { - bytes32[] memory availableTags = new bytes32[](2); + bytes32[] memory availableTags = new bytes32[](2); availableTags[0] = "Count"; availableTags[1] = "Transfer Restriction"; return availableTags; diff --git a/contracts/modules/TransferManager/GeneralTransferManager.sol b/contracts/modules/TransferManager/GeneralTransferManager.sol index 707927b93..92bdcdce2 100644 --- a/contracts/modules/TransferManager/GeneralTransferManager.sol +++ b/contracts/modules/TransferManager/GeneralTransferManager.sol @@ -144,12 +144,14 @@ contract GeneralTransferManager is ITransferManager { } /** - * @notice default implementation of verifyTransfer used by SecurityToken - * If the transfer request comes from the STO, it only checks that the investor is in the whitelist - * If the transfer request comes from a token holder, it checks that: - * a) Both are on the whitelist - * b) Seller's sale lockup period is over - * c) Buyer's purchase lockup is over + * @notice default implementation of verifyTransfer used by SecurityToken + * If the transfer request comes from the STO, it only checks that the investor is in the whitelist + * If the transfer request comes from a token holder, it checks that: + * a) Both are on the whitelist + * b) Seller's sale lockup period is over + * c) Buyer's purchase lockup is over + * @param _from Address of the sender + * @param _to Address of the receiver */ function verifyTransfer(address _from, address _to, uint256 /*_amount*/, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { if (!paused) { @@ -259,16 +261,6 @@ contract GeneralTransferManager is ITransferManager { require(signer == Ownable(securityToken).owner() || signer == signingAddress, "Incorrect signer"); } - /** - * @notice Return the permissions flag that are associated with general trnasfer manager - */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](2); - allPermissions[0] = WHITELIST; - allPermissions[1] = FLAGS; - return allPermissions; - } - /** * @notice Internal function used to check whether the investor is in the whitelist or not & also checks whether the KYC of investor get expired or not @@ -287,4 +279,14 @@ contract GeneralTransferManager is ITransferManager { return attached; } + /** + * @notice Return the permissions flag that are associated with general trnasfer manager + */ + function getPermissions() public view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](2); + allPermissions[0] = WHITELIST; + allPermissions[1] = FLAGS; + return allPermissions; + } + } diff --git a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol index 60e85f8f4..5ef1953b4 100644 --- a/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/GeneralTransferManagerFactory.sol @@ -82,7 +82,7 @@ contract GeneralTransferManagerFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters."; diff --git a/contracts/modules/TransferManager/ITransferManager.sol b/contracts/modules/TransferManager/ITransferManager.sol index 3f736801c..a8cfa4475 100644 --- a/contracts/modules/TransferManager/ITransferManager.sol +++ b/contracts/modules/TransferManager/ITransferManager.sol @@ -18,11 +18,11 @@ contract ITransferManager is Module, Pausable { function verifyTransfer(address _from, address _to, uint256 _amount, bytes _data, bool _isTransfer) public returns(Result); - function unpause() onlyOwner public { + function unpause() public onlyOwner { super._unpause(); } - function pause() onlyOwner public { + function pause() public onlyOwner { super._pause(); } } diff --git a/contracts/modules/TransferManager/LockupVolumeRestrictionTM.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTM.sol index bc9606e79..4ddb43f29 100644 --- a/contracts/modules/TransferManager/LockupVolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/LockupVolumeRestrictionTM.sol @@ -78,81 +78,91 @@ contract LockupVolumeRestrictionTM is ITransferManager { /** * @notice Lets the admin create a volume restriction lockup for a given address. - * @param userAddress Address of the user whose tokens should be locked up - * @param lockUpPeriodSeconds Total period of lockup (seconds) - * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) - * @param startTime When this lockup starts (seconds) - * @param totalAmount Total amount of locked up tokens + * @param _userAddress Address of the user whose tokens should be locked up + * @param _lockUpPeriodSeconds Total period of lockup (seconds) + * @param _releaseFrequencySeconds How often to release a tranche of tokens (seconds) + * @param _startTime When this lockup starts (seconds) + * @param _totalAmount Total amount of locked up tokens */ - function addLockUp(address userAddress, uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount) public withPerm(ADMIN) { - - _checkLockUpParams(lockUpPeriodSeconds, releaseFrequencySeconds, totalAmount); + function addLockUp( + address _userAddress, + uint _lockUpPeriodSeconds, + uint _releaseFrequencySeconds, + uint _startTime, + uint _totalAmount + ) public withPerm(ADMIN) { + uint256 startTime = _startTime; + _checkLockUpParams(_lockUpPeriodSeconds, _releaseFrequencySeconds, _totalAmount); // if a startTime of 0 is passed in, then start now. if (startTime == 0) { startTime = now; } - lockUps[userAddress].push(LockUp(lockUpPeriodSeconds, releaseFrequencySeconds, startTime, totalAmount, 0)); + lockUps[_userAddress].push(LockUp(_lockUpPeriodSeconds, _releaseFrequencySeconds, startTime, _totalAmount, 0)); emit AddNewLockUp( - userAddress, - lockUpPeriodSeconds, - releaseFrequencySeconds, + _userAddress, + _lockUpPeriodSeconds, + _releaseFrequencySeconds, startTime, - totalAmount, - lockUps[userAddress].length - 1 + _totalAmount, + lockUps[_userAddress].length - 1 ); } /** * @notice Lets the admin create multiple volume restriction lockups for multiple given addresses. - * @param userAddresses Array of address of the user whose tokens should be locked up - * @param lockUpPeriodsSeconds Array of total periods of lockup (seconds) - * @param releaseFrequenciesSeconds Array of how often to release a tranche of tokens (seconds) - * @param startTimes Array of When this lockup starts (seconds) - * @param totalAmounts Array of total amount of locked up tokens + * @param _userAddresses Array of address of the user whose tokens should be locked up + * @param _lockUpPeriodsSeconds Array of total periods of lockup (seconds) + * @param _releaseFrequenciesSeconds Array of how often to release a tranche of tokens (seconds) + * @param _startTimes Array of When this lockup starts (seconds) + * @param _totalAmounts Array of total amount of locked up tokens */ - function addLockUpMulti(address[] userAddresses, uint[] lockUpPeriodsSeconds, uint[] releaseFrequenciesSeconds, uint[] startTimes, uint[] totalAmounts) external withPerm(ADMIN) { - - // make sure input params are sane + function addLockUpMulti( + address[] _userAddresses, + uint[] _lockUpPeriodsSeconds, + uint[] _releaseFrequenciesSeconds, + uint[] _startTimes, + uint[] _totalAmounts + ) external withPerm(ADMIN) { require( - userAddresses.length == lockUpPeriodsSeconds.length && - userAddresses.length == releaseFrequenciesSeconds.length && - userAddresses.length == startTimes.length && - userAddresses.length == totalAmounts.length, - "Input array length mis-match" + _userAddresses.length == _lockUpPeriodsSeconds.length && + _userAddresses.length == _releaseFrequenciesSeconds.length && + _userAddresses.length == _startTimes.length && + _userAddresses.length == _totalAmounts.length, + "Input array length mismatch" ); - for (uint i = 0; i < userAddresses.length; i++) { - addLockUp(userAddresses[i], lockUpPeriodsSeconds[i], releaseFrequenciesSeconds[i], startTimes[i], totalAmounts[i]); + for (uint i = 0; i < _userAddresses.length; i++) { + addLockUp(_userAddresses[i], _lockUpPeriodsSeconds[i], _releaseFrequenciesSeconds[i], _startTimes[i], _totalAmounts[i]); } } /** * @notice Lets the admin remove a user's lock up - * @param userAddress Address of the user whose tokens are locked up - * @param lockUpIndex The index of the LockUp to remove for the given userAddress + * @param _userAddress Address of the user whose tokens are locked up + * @param _lockUpIndex The index of the LockUp to remove for the given userAddress */ - function removeLockUp(address userAddress, uint lockUpIndex) public withPerm(ADMIN) { - LockUp[] storage userLockUps = lockUps[userAddress]; - require(lockUpIndex < userLockUps.length, "Array out of bounds exception"); + function removeLockUp(address _userAddress, uint _lockUpIndex) public withPerm(ADMIN) { + LockUp[] storage userLockUps = lockUps[_userAddress]; + require(_lockUpIndex < userLockUps.length, "Array out of bounds exception"); - LockUp memory toRemove = userLockUps[lockUpIndex]; + LockUp memory toRemove = userLockUps[_lockUpIndex]; emit RemoveLockUp( - userAddress, + _userAddress, toRemove.lockUpPeriodSeconds, toRemove.releaseFrequencySeconds, toRemove.startTime, toRemove.totalAmount, - lockUpIndex + _lockUpIndex ); - if (lockUpIndex < userLockUps.length - 1) { + if (_lockUpIndex < userLockUps.length - 1) { // move the last element in the array into the index that is desired to be removed. - userLockUps[lockUpIndex] = userLockUps[userLockUps.length - 1]; + userLockUps[_lockUpIndex] = userLockUps[userLockUps.length - 1]; } // delete the last element userLockUps.length--; @@ -160,58 +170,75 @@ contract LockupVolumeRestrictionTM is ITransferManager { /** * @notice Lets the admin modify a volume restriction lockup for a given address. - * @param userAddress Address of the user whose tokens should be locked up - * @param lockUpIndex The index of the LockUp to edit for the given userAddress - * @param lockUpPeriodSeconds Total period of lockup (seconds) - * @param releaseFrequencySeconds How often to release a tranche of tokens (seconds) - * @param startTime When this lockup starts (seconds) - * @param totalAmount Total amount of locked up tokens + * @param _userAddress Address of the user whose tokens should be locked up + * @param _lockUpIndex The index of the LockUp to edit for the given userAddress + * @param _lockUpPeriodSeconds Total period of lockup (seconds) + * @param _releaseFrequencySeconds How often to release a tranche of tokens (seconds) + * @param _startTime When this lockup starts (seconds) + * @param _totalAmount Total amount of locked up tokens */ - function modifyLockUp(address userAddress, uint lockUpIndex, uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount) public withPerm(ADMIN) { - require(lockUpIndex < lockUps[userAddress].length, "Array out of bounds exception"); - + function modifyLockUp( + address _userAddress, + uint _lockUpIndex, + uint _lockUpPeriodSeconds, + uint _releaseFrequencySeconds, + uint _startTime, + uint _totalAmount + ) public withPerm(ADMIN) { + require(_lockUpIndex < lockUps[_userAddress].length, "Array out of bounds exception"); + + uint256 startTime = _startTime; // if a startTime of 0 is passed in, then start now. if (startTime == 0) { startTime = now; } - _checkLockUpParams(lockUpPeriodSeconds, releaseFrequencySeconds, totalAmount); + _checkLockUpParams(_lockUpPeriodSeconds, _releaseFrequencySeconds, _totalAmount); // Get the lockup from the master list and edit it - lockUps[userAddress][lockUpIndex] = LockUp( - lockUpPeriodSeconds, - releaseFrequencySeconds, + lockUps[_userAddress][_lockUpIndex] = LockUp( + _lockUpPeriodSeconds, + _releaseFrequencySeconds, startTime, - totalAmount, - lockUps[userAddress][lockUpIndex].alreadyWithdrawn + _totalAmount, + lockUps[_userAddress][_lockUpIndex].alreadyWithdrawn ); emit ModifyLockUp( - userAddress, - lockUpPeriodSeconds, - releaseFrequencySeconds, + _userAddress, + _lockUpPeriodSeconds, + _releaseFrequencySeconds, startTime, - totalAmount, - lockUpIndex + _totalAmount, + _lockUpIndex ); } /** * @notice Get the length of the lockups array for a specific user address - * @param userAddress Address of the user whose tokens should be locked up + * @param _userAddress Address of the user whose tokens should be locked up */ - function getLockUpsLength(address userAddress) public view returns (uint) { - return lockUps[userAddress].length; + function getLockUpsLength(address _userAddress) public view returns (uint) { + return lockUps[_userAddress].length; } /** * @notice Get a specific element in a user's lockups array given the user's address and the element index - * @param userAddress Address of the user whose tokens should be locked up - * @param lockUpIndex The index of the LockUp to edit for the given userAddress + * @param _userAddress Address of the user whose tokens should be locked up + * @param _lockUpIndex The index of the LockUp to edit for the given userAddress */ - function getLockUp(address userAddress, uint lockUpIndex) public view returns (uint lockUpPeriodSeconds, uint releaseFrequencySeconds, uint startTime, uint totalAmount, uint alreadyWithdrawn) { - require(lockUpIndex < lockUps[userAddress].length, "Array out of bounds exception"); - LockUp storage userLockUp = lockUps[userAddress][lockUpIndex]; + function getLockUp( + address _userAddress, + uint _lockUpIndex) + public view returns ( + uint lockUpPeriodSeconds, + uint releaseFrequencySeconds, + uint startTime, + uint totalAmount, + uint alreadyWithdrawn + ) { + require(_lockUpIndex < lockUps[_userAddress].length, "Array out of bounds exception"); + LockUp storage userLockUp = lockUps[_userAddress][_lockUpIndex]; return ( userLockUp.lockUpPeriodSeconds, userLockUp.releaseFrequencySeconds, @@ -221,22 +248,6 @@ contract LockupVolumeRestrictionTM is ITransferManager { ); } - /** - * @notice This function returns the signature of configure function - */ - function getInitFunction() public pure returns (bytes4) { - return bytes4(0); - } - - /** - * @notice Return the permissions flag that are associated with Percentage transfer Manager - */ - function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); - allPermissions[0] = ADMIN; - return allPermissions; - } - /** * @notice Takes a userAddress as input, and returns a uint that represents the number of tokens allowed to be withdrawn right now * @param userAddress Address of the user whose lock ups should be checked @@ -322,7 +333,12 @@ contract LockupVolumeRestrictionTM is ITransferManager { return _checkIfUnlockedTokenTransferIsPossible(userAddress, amount, tokenSums[1], tokenSums[2]); } - function _checkIfUnlockedTokenTransferIsPossible(address userAddress, uint amount, uint totalSum, uint alreadyWithdrawnSum) internal view returns (Result) { + function _checkIfUnlockedTokenTransferIsPossible( + address userAddress, + uint amount, + uint totalSum, + uint alreadyWithdrawnSum + ) internal view returns (Result) { // the amount the user wants to withdraw is greater than their allowed amounts according to the lockups. however, if the user has like, 10 tokens, but only 4 are locked up, we should let the transfer go through for those 6 that aren't locked up uint currentUserBalance = ISecurityToken(securityToken).balanceOf(userAddress); uint stillLockedAmount = totalSum.sub(alreadyWithdrawnSum); @@ -371,4 +387,20 @@ contract LockupVolumeRestrictionTM is ITransferManager { "The amount to be released per period is more granular than allowed by the token" ); } + + /** + * @notice This function returns the signature of configure function + */ + function getInitFunction() public pure returns (bytes4) { + return bytes4(0); + } + + /** + * @notice Return the permissions flag that are associated with Percentage transfer Manager + */ + function getPermissions() public view returns(bytes32[]) { + bytes32[] memory allPermissions = new bytes32[](1); + allPermissions[0] = ADMIN; + return allPermissions; + } } diff --git a/contracts/modules/TransferManager/LockupVolumeRestrictionTMFactory.sol b/contracts/modules/TransferManager/LockupVolumeRestrictionTMFactory.sol index 307390138..9d0e0fa26 100644 --- a/contracts/modules/TransferManager/LockupVolumeRestrictionTMFactory.sol +++ b/contracts/modules/TransferManager/LockupVolumeRestrictionTMFactory.sol @@ -84,7 +84,7 @@ contract LockupVolumeRestrictionTMFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Allows an issuer to set lockup periods for user addresses, with funds distributed over time. Init function takes no parameters."; diff --git a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol index e4f5d35f0..aa3810747 100644 --- a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol +++ b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol @@ -79,14 +79,12 @@ contract ManualApprovalTransferManager is ITransferManager { return bytes4(0); } - /** - * @notice default implementation of verifyTransfer used by SecurityToken - * If the transfer request comes from the STO, it only checks that the investor is in the whitelist - * If the transfer request comes from a token holder, it checks that: - * a) Both are on the whitelist - * b) Seller's sale lockup period is over - * c) Buyer's purchase lockup is over - */ + /** @notice Used to verify the transfer transaction and allow a manually approved transqaction to bypass other restrictions + * @param _from Address of the sender + * @param _to Address of the receiver + * @param _amount The amount of tokens to transfer + * @param _isTransfer Whether or not this is an actual transfer or just a test to see if the tokens would be transferrable + */ function verifyTransfer(address _from, address _to, uint256 _amount, bytes /* _data */, bool _isTransfer) public returns(Result) { // function must only be called by the associated security token if _isTransfer == true require(_isTransfer == false || msg.sender == securityToken, "Sender is not owner"); diff --git a/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol b/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol index e3ad15901..4de95959a 100644 --- a/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/ManualApprovalTransferManagerFactory.sol @@ -83,7 +83,7 @@ contract ManualApprovalTransferManagerFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters."; diff --git a/contracts/modules/TransferManager/PercentageTransferManager.sol b/contracts/modules/TransferManager/PercentageTransferManager.sol index 77b79639f..8830bc5b8 100644 --- a/contracts/modules/TransferManager/PercentageTransferManager.sol +++ b/contracts/modules/TransferManager/PercentageTransferManager.sol @@ -42,7 +42,11 @@ contract PercentageTransferManager is ITransferManager { { } - /// @notice Used to verify the transfer transaction according to the rule implemented in the trnasfer managers + /** @notice Used to verify the transfer transaction and prevent a given account to end up with more tokens than allowed + * @param _from Address of the sender + * @param _to Address of the receiver + * @param _amount The amount of tokens to transfer + */ function verifyTransfer(address _from, address _to, uint256 _amount, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { if (!paused) { if (_from == address(0) && allowPrimaryIssuance) { diff --git a/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol b/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol index 573c79ba1..9d6523651 100644 --- a/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/PercentageTransferManagerFactory.sol @@ -34,7 +34,7 @@ contract PercentageTransferManagerFactory is ModuleFactory { require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); PercentageTransferManager percentageTransferManager = new PercentageTransferManager(msg.sender, address(polyToken)); require(Util.getSig(_data) == percentageTransferManager.getInitFunction(), "Provided data is not valid"); - require(address(percentageTransferManager).call(_data), "Un-successfull call"); + require(address(percentageTransferManager).call(_data), "Unsuccessful call"); emit GenerateModuleFromFactory(address(percentageTransferManager), getName(), address(this), msg.sender, setupCost, now); return address(percentageTransferManager); @@ -86,7 +86,7 @@ contract PercentageTransferManagerFactory is ModuleFactory { } /** - * @notice Get the Instructions that helped to used the module + * @notice Returns the instructions associated with the module */ function getInstructions() external view returns(string) { return "Allows an issuer to restrict the total number of non-zero token holders"; diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTM.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTM.sol index 2f507f1a6..f9d260fac 100644 --- a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTM.sol @@ -52,7 +52,10 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { } - /// @notice Used to verify the transfer transaction according to the rule implemented in the transfer manager + /** @notice Used to verify the transfer transaction and prevent an account from sending more tokens than allowed in a single transfer + * @param _from Address of the sender + * @param _amount The amount of tokens to transfer + */ function verifyTransfer(address _from, address /* _to */, uint256 _amount, bytes /* _data */, bool /* _isTransfer */) public returns(Result) { bool validTransfer; @@ -69,11 +72,11 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { validTransfer = (_amount.mul(10**18).div(ISecurityToken(securityToken).totalSupply())) <= globalTransferLimitInPercentage; } } else { - if (specialTransferLimitsInTokens[_from] > 0) { - validTransfer = _amount <= specialTransferLimitsInTokens[_from]; - } else { - validTransfer = _amount <= globalTransferLimitInTokens; - } + if (specialTransferLimitsInTokens[_from] > 0) { + validTransfer = _amount <= specialTransferLimitsInTokens[_from]; + } else { + validTransfer = _amount <= globalTransferLimitInTokens; + } } if (validTransfer) return Result.NA; return Result.INVALID; @@ -84,7 +87,11 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { * @param _isTransferLimitInPercentage true if the transfer limit is in percentage else false * @param _globalTransferLimitInPercentageOrToken transfer limit per single transaction. */ - function configure(bool _isTransferLimitInPercentage, uint256 _globalTransferLimitInPercentageOrToken, bool _allowPrimaryIssuance) public onlyFactory { + function configure( + bool _isTransferLimitInPercentage, + uint256 _globalTransferLimitInPercentageOrToken, + bool _allowPrimaryIssuance + ) public onlyFactory { isTransferLimitInPercentage = _isTransferLimitInPercentage; if (isTransferLimitInPercentage) { changeGlobalLimitInPercentage(_globalTransferLimitInPercentageOrToken); @@ -148,7 +155,7 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { */ function changeGlobalLimitInPercentage(uint256 _newGlobalTransferLimitInPercentage) public withPerm(ADMIN) { require(isTransferLimitInPercentage, "Transfer limit not set in Percentage"); - require(_newGlobalTransferLimitInPercentage > 0 && _newGlobalTransferLimitInPercentage <= 100 * 10 ** 16); + require(_newGlobalTransferLimitInPercentage > 0 && _newGlobalTransferLimitInPercentage <= 100 * 10 ** 16, "Limit not within [0,100]"); emit GlobalTransferLimitInPercentageSet(_newGlobalTransferLimitInPercentage, globalTransferLimitInPercentage); globalTransferLimitInPercentage = _newGlobalTransferLimitInPercentage; @@ -229,7 +236,7 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { * @param _wallet wallet address */ function removeTransferLimitInPercentage(address _wallet) public withPerm(ADMIN) { - require(specialTransferLimitsInPercentages[_wallet] > 0 , "Wallet Address does not have a transfer limit"); + require(specialTransferLimitsInPercentages[_wallet] > 0, "Wallet Address does not have a transfer limit"); specialTransferLimitsInPercentages[_wallet] = 0; emit TransferLimitInPercentageRemoved(_wallet); } @@ -239,7 +246,7 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { * @param _wallet wallet address */ function removeTransferLimitInTokens(address _wallet) public withPerm(ADMIN) { - require(specialTransferLimitsInTokens[_wallet] > 0 , "Wallet Address does not have a transfer limit"); + require(specialTransferLimitsInTokens[_wallet] > 0, "Wallet Address does not have a transfer limit"); specialTransferLimitsInTokens[_wallet] = 0; emit TransferLimitInTokensRemoved(_wallet); } @@ -251,9 +258,9 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { * @dev The manager has to be configured to use tokens as limit */ function setTransferLimitInTokensMulti(address[] _wallets, uint[] _transferLimits) public withPerm(ADMIN) { - require(_wallets.length > 0, "Wallets cannot be empty"); + require(_wallets.length > 0, "Wallets cannot be empty"); require(_wallets.length == _transferLimits.length); - for (uint256 i=0; i < _wallets.length; i++ ) { + for (uint256 i = 0; i < _wallets.length; i++ ) { setTransferLimitInTokens(_wallets[i], _transferLimits[i]); } } @@ -268,7 +275,7 @@ contract SingleTradeVolumeRestrictionTM is ITransferManager { function setTransferLimitInPercentageMulti(address[] _wallets, uint[] _transferLimitsInPercentage) public withPerm(ADMIN) { require(_wallets.length > 0, "Wallets cannot be empty"); require(_wallets.length == _transferLimitsInPercentage.length); - for (uint256 i=0; i < _wallets.length; i++) { + for (uint256 i = 0; i < _wallets.length; i++) { setTransferLimitInPercentage(_wallets[i], _transferLimitsInPercentage[i]); } } diff --git a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTMFactory.sol b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTMFactory.sol index 7b5c47ffb..d5795647c 100644 --- a/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTMFactory.sol +++ b/contracts/modules/TransferManager/SingleTradeVolumeRestrictionTMFactory.sol @@ -37,7 +37,7 @@ contract SingleTradeVolumeRestrictionTMFactory is ModuleFactory { SingleTradeVolumeRestrictionTM singleTradeVolumeRestrictionManager = new SingleTradeVolumeRestrictionTM(msg.sender, address(polyToken)); require(Util.getSig(_data) == singleTradeVolumeRestrictionManager.getInitFunction(), "Provided data is not valid"); - require(address(singleTradeVolumeRestrictionManager).call(_data), "Un-successfull call"); + require(address(singleTradeVolumeRestrictionManager).call(_data), "Unsuccessful call"); emit GenerateModuleFromFactory(address(singleTradeVolumeRestrictionManager), getName(), address(this), msg.sender, setupCost, now); return address(singleTradeVolumeRestrictionManager); } From 468b04772ecd1a395e19ed91f3a0c9cd87638ab3 Mon Sep 17 00:00:00 2001 From: Pablo Ruiz Date: Sun, 14 Oct 2018 08:57:21 -0300 Subject: [PATCH 135/142] minor linter error fixes --- contracts/interfaces/IERC20.sol | 22 ++++++++++---------- contracts/interfaces/IModuleRegistry.sol | 2 +- contracts/interfaces/IOwnable.sol | 26 ++++++++++++------------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/contracts/interfaces/IERC20.sol b/contracts/interfaces/IERC20.sol index c38f4c32f..b1d36463f 100644 --- a/contracts/interfaces/IERC20.sol +++ b/contracts/interfaces/IERC20.sol @@ -5,15 +5,15 @@ pragma solidity ^0.4.24; * @dev see https://github.com/ethereum/EIPs/issues/20 */ interface IERC20 { - function decimals() external view returns (uint8); - function totalSupply() external view returns (uint256); - function balanceOf(address _owner) external view returns (uint256); - function allowance(address _owner, address _spender) external view returns (uint256); - function transfer(address _to, uint256 _value) external returns (bool); - function transferFrom(address _from, address _to, uint256 _value) external returns (bool); - function approve(address _spender, uint256 _value) external returns (bool); - function decreaseApproval(address _spender, uint _subtractedValue) external returns (bool); - function increaseApproval(address _spender, uint _addedValue) external returns (bool); - event Transfer(address indexed from, address indexed to, uint256 value); - event Approval(address indexed owner, address indexed spender, uint256 value); + function decimals() external view returns (uint8); + function totalSupply() external view returns (uint256); + function balanceOf(address _owner) external view returns (uint256); + function allowance(address _owner, address _spender) external view returns (uint256); + function transfer(address _to, uint256 _value) external returns (bool); + function transferFrom(address _from, address _to, uint256 _value) external returns (bool); + function approve(address _spender, uint256 _value) external returns (bool); + function decreaseApproval(address _spender, uint _subtractedValue) external returns (bool); + function increaseApproval(address _spender, uint _addedValue) external returns (bool); + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); } diff --git a/contracts/interfaces/IModuleRegistry.sol b/contracts/interfaces/IModuleRegistry.sol index a2742fb7c..0ca6044e4 100644 --- a/contracts/interfaces/IModuleRegistry.sol +++ b/contracts/interfaces/IModuleRegistry.sol @@ -26,7 +26,7 @@ interface IModuleRegistry { /** * @notice Called by Polymath to verify modules for SecurityToken to use. * @notice A module can not be used by an ST unless first approved/verified by Polymath - * @notice (The only exception to this is that the author of the module is the owner of the ST) + * @notice (The only exception to this is that the author of the module is the owner of the ST - Only if enabled by the FeatureRegistry) * @param _moduleFactory is the address of the module factory to be registered */ function verifyModule(address _moduleFactory, bool _verified) external; diff --git a/contracts/interfaces/IOwnable.sol b/contracts/interfaces/IOwnable.sol index de8a8d14f..e4f427bd8 100644 --- a/contracts/interfaces/IOwnable.sol +++ b/contracts/interfaces/IOwnable.sol @@ -7,20 +7,20 @@ pragma solidity ^0.4.24; * functions, this simplifies the implementation of "user permissions". */ interface IOwnable { - /** - * @dev Returns owner - */ - function owner() external view returns (address); + /** + * @dev Returns owner + */ + function owner() external view returns (address); - /** - * @dev Allows the current owner to relinquish control of the contract. - */ - function renounceOwnership() external; + /** + * @dev Allows the current owner to relinquish control of the contract. + */ + function renounceOwnership() external; - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param _newOwner The address to transfer ownership to. - */ - function transferOwnership(address _newOwner) external; + /** + * @dev Allows the current owner to transfer control of the contract to a newOwner. + * @param _newOwner The address to transfer ownership to. + */ + function transferOwnership(address _newOwner) external; } From df996a17860501c37d07db43c8af2dfbdef8e142 Mon Sep 17 00:00:00 2001 From: Satyam Agrawal Date: Tue, 16 Oct 2018 16:28:05 +0530 Subject: [PATCH 136/142] Increase coverage (#342) * branches coverage reached to 85 % * increase coverage of transferManagers * improve the coverage of token * introduced withdrawERC20() in the changelog * fix * minor fixes --- .solcover.js | 2 +- CHANGELOG.md | 5 +- contracts/ModuleRegistry.sol | 1 - contracts/SecurityTokenRegistry.sol | 1 + contracts/interfaces/ISecurityToken.sol | 7 +- contracts/mocks/MockBurnFactory.sol | 34 ++++ contracts/mocks/MockFactory.sol | 101 +++-------- contracts/mocks/MockRedemptionManager.sol | 45 +++++ contracts/mocks/MockWrongTypeFactory.sol | 31 ++++ contracts/mocks/TestSTOFactory.sol | 68 +------ contracts/modules/Burn/TrackedRedemption.sol | 2 +- .../ManualApprovalTransferManager.sol | 2 +- contracts/proxy/OwnedUpgradeabilityProxy.sol | 2 +- contracts/tokens/SecurityToken.sol | 19 +- test/b_capped_sto.js | 102 +++++++++-- test/d_count_transfer_manager.js | 100 ++++++++++ test/g_general_permission_manager.js | 138 +++++++------- test/h_general_transfer_manager.js | 94 +++++++++- test/helpers/createInstances.js | 28 +++ test/i_Issuance.js | 3 +- test/j_manual_approval_transfer_manager.js | 39 ++-- test/k_module_registry.js | 171 ++++++++++++++++-- test/l_percentage_transfer_manager.js | 17 ++ test/m_presale_sto.js | 107 ++++++++++- test/n_security_token_registry.js | 154 ++++++++++++++-- test/o_security_token.js | 161 ++++++++++++++++- test/p_usd_tiered_sto.js | 91 +++++++++- test/s_v130_to_v140_upgrade.js | 13 +- test/t_security_token_registry_proxy.js | 8 + test/u_module_registry_proxy.js | 8 +- test/v_tracked_redemptions.js | 16 ++ ...kup_volume_restriction_transfer_manager.js | 68 ++++--- test/x_single_trade_volume_restriction.js | 9 + 33 files changed, 1309 insertions(+), 338 deletions(-) create mode 100644 contracts/mocks/MockBurnFactory.sol create mode 100644 contracts/mocks/MockRedemptionManager.sol create mode 100644 contracts/mocks/MockWrongTypeFactory.sol diff --git a/.solcover.js b/.solcover.js index c7a6ed7d1..ffd077e28 100644 --- a/.solcover.js +++ b/.solcover.js @@ -4,6 +4,6 @@ module.exports = { copyPackages: ['openzeppelin-solidity'], testCommand: 'node ../node_modules/.bin/truffle test `find test/*.js ! -name a_poly_oracle.js -and ! -name s_v130_to_v140_upgrade.js` --network coverage', deepSkip: true, - skipFiles: ['external', 'flat', 'helpers', 'mocks', 'oracles'], + skipFiles: ['external', 'flat', 'helpers', 'mocks', 'oracles', 'libraries/KindMath.sol', 'storage'], forceParse: ['mocks', 'oracles'] }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a4896b14..c4b8fdb42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,11 +26,12 @@ All notable changes to this project will be documented in this file. * Add `getReputationOfFactory()` & `getModuleListOfType()` functions to get the array type data from the ModuleRegistry contract. * Add `_setupCost` in `LogGenerateModuleFromFactory` event. * Add new function `getAllModulesByName()`, To get the list of modules having the same name. #198. -* Add new function `modifyTickerDetails()`, To modify the details of undeployed ticker. #230 +* Add new function `modifyTickerDetails()`, To modify the details of undeployed ticker. #230 ## Fixed * Generalize the STO varaible names and added them in `ISTO.sol` to use the common standard in all STOs. -* Generalize the event when any new token get registered with the polymath ecosystem. `LogNewSecurityToken` should emit _ticker, _name, _securityTokenAddress, _owner, _addedAt, _registrant respectively. #230 +* Generalize the event when any new token get registered with the polymath ecosystem. `LogNewSecurityToken` should emit _ticker, _name, _securityTokenAddress, _owner, _addedAt, _registrant respectively. #230 +* Change the function name of `withdraPoly` to `withdrawERC20` and make the function generalize to extract tokens from the ST contract. parmeters are contract address and the value need to extract from the securityToken. ## Removed * Remove `swarmHash` from the `registerTicker(), addCustomTicker(), generateSecurityToken(), addCustomSecurityToken()` functions of TickerRegistry.sol and SecurityTokenRegistry.sol. #230 diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index b7b85c2b5..03c5f3016 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -126,7 +126,6 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { require(getBool(Encoder.getKey("verified", _moduleFactory)), "ModuleFactory must be verified"); } require(_isCompatibleModule(_moduleFactory, msg.sender), "Version should within the compatible range of ST"); - require(getUint(Encoder.getKey("registry",_moduleFactory)) != 0, "ModuleFactory type should not be 0"); pushArray(Encoder.getKey("reputation", _moduleFactory), msg.sender); emit ModuleUsed(_moduleFactory, msg.sender); } diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index 9286a1a7f..29ed14a8a 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -669,6 +669,7 @@ contract SecurityTokenRegistry is ISecurityTokenRegistry, EternalStorage { * @param _patch Patch version of the proxy */ function setProtocolVersion(address _STFactoryAddress, uint8 _major, uint8 _minor, uint8 _patch) external onlyOwner { + require(_STFactoryAddress != address(0), "0x address is not allowed"); _setProtocolVersion(_STFactoryAddress, _major, _minor, _patch); } diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index e099006bc..c845cc30d 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -127,12 +127,13 @@ interface ISecurityToken { */ function investors(uint256 _index) external view returns (address); - /** - * @notice allows the owner to withdraw unspent POLY stored by them on the ST. + /** + * @notice allows the owner to withdraw unspent POLY stored by them on the ST or any ERC20 token. * @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee. + * @param _tokenContract Address of the ERC20Basic compliance token * @param _value amount of POLY to withdraw */ - function withdrawPoly(uint256 _value) external; + function withdrawERC20(address _tokenContract, uint256 _value) external; /** * @notice allows owner to approve more POLY to one of the modules diff --git a/contracts/mocks/MockBurnFactory.sol b/contracts/mocks/MockBurnFactory.sol new file mode 100644 index 000000000..c21b474f1 --- /dev/null +++ b/contracts/mocks/MockBurnFactory.sol @@ -0,0 +1,34 @@ +pragma solidity ^0.4.24; + +import "./MockRedemptionManager.sol"; +import "../modules/Burn/TrackedRedemptionFactory.sol"; + +/** + * @title Mock Contract Not fit for production environment + */ + +contract MockBurnFactory is TrackedRedemptionFactory { + + /** + * @notice Constructor + * @param _polyAddress Address of the polytoken + */ + constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public + TrackedRedemptionFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + { + } + + /** + * @notice used to launch the Module with the help of factory + * @return address Contract address of the Module + */ + function deploy(bytes /*_data*/) external returns(address) { + if(setupCost > 0) + require(polyToken.transferFrom(msg.sender, owner, setupCost), "Unable to pay setup cost"); + //Check valid bytes - can only call module init function + MockRedemptionManager mockRedemptionManager = new MockRedemptionManager(msg.sender, address(polyToken)); + emit GenerateModuleFromFactory(address(mockRedemptionManager), getName(), address(this), msg.sender, setupCost, now); + return address(mockRedemptionManager); + } + +} diff --git a/contracts/mocks/MockFactory.sol b/contracts/mocks/MockFactory.sol index 5f2469cde..627efb71c 100644 --- a/contracts/mocks/MockFactory.sol +++ b/contracts/mocks/MockFactory.sol @@ -1,99 +1,42 @@ pragma solidity ^0.4.24; -import "../modules/STO/DummySTO.sol"; -import "../modules/ModuleFactory.sol"; -import "../libraries/Util.sol"; +import "../modules/STO/DummySTOFactory.sol"; -contract MockFactory is ModuleFactory { +/** + * @title Mock Contract Not fit for production environment + */ +contract MockFactory is DummySTOFactory { + + bool public switchTypes = false; /** * @notice Constructor * @param _polyAddress Address of the polytoken */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public - ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + DummySTOFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { - version = "1.0.0"; - name = "Mock"; - title = "Mock Manager"; - description = "MockManager"; - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - } - /** - * @notice used to launch the Module with the help of factory - * @param _data Data used for the intialization of the module factory variables - * @return address Contract address of the Module - */ - function deploy(bytes _data) external returns(address) { - if(setupCost > 0) - require(polyToken.transferFrom(msg.sender, owner, setupCost), "Unable to pay setup cost"); - //Check valid bytes - can only call module init function - DummySTO dummySTO = new DummySTO(msg.sender, address(polyToken)); - //Checks that _data is valid (not calling anything it shouldn't) - require(Util.getSig(_data) == dummySTO.getInitFunction(), "Invalid initialisation"); - require(address(dummySTO).call(_data), "Unsuccessfull initialisation"); - return address(dummySTO); } /** * @notice Type of the Module factory */ function getTypes() external view returns(uint8[]) { - uint8[] memory res = new uint8[](0); - return res; - } - - /** - * @notice Get the name of the Module - */ - function getName() public view returns(bytes32) { - return name; - } - - /** - * @notice Get the description of the Module - */ - function getDescription() external view returns(string) { - return description; - } - - /** - * @notice Get the title of the Module - */ - function getTitle() external view returns(string) { - return title; - } - - /** - * @notice Get the version of the Module - */ - function getVersion() external view returns(string) { - return version; - } - - /** - * @notice Get the setup cost of the module - */ - function getSetupCost() external view returns (uint256) { - return setupCost; - } - - /** - * @notice Returns the instructions associated with the module - */ - function getInstructions() external view returns(string) { - return "Mock Manager - This is mock in nature"; - } - - /** - * @notice Get the tags related to the module factory - */ - function getTags() external view returns(bytes32[]) { - bytes32[] memory availableTags = new bytes32[](4); - availableTags[0] = "Mock"; - return availableTags; + if (!switchTypes) { + uint8[] memory types = new uint8[](0); + return types; + } else { + uint8[] memory res = new uint8[](2); + res[0] = 1; + res[1] = 1; + return res; + } + + } + + function changeTypes() external onlyOwner { + switchTypes = !switchTypes; } } diff --git a/contracts/mocks/MockRedemptionManager.sol b/contracts/mocks/MockRedemptionManager.sol new file mode 100644 index 000000000..a2a0a6f7c --- /dev/null +++ b/contracts/mocks/MockRedemptionManager.sol @@ -0,0 +1,45 @@ +pragma solidity ^0.4.24; + +import "../modules/Burn/TrackedRedemption.sol"; + +/** + * @title Burn module for burning tokens and keeping track of burnt amounts + */ +contract MockRedemptionManager is TrackedRedemption { + + mapping (address => uint256) tokenToRedeem; + + event RedeemedTokenByOwner(address _investor, address _byWhoom, uint256 _value, uint256 _timestamp); + + /** + * @notice Constructor + * @param _securityToken Address of the security token + * @param _polyAddress Address of the polytoken + */ + constructor (address _securityToken, address _polyAddress) public + TrackedRedemption(_securityToken, _polyAddress) + { + } + + /** + * @notice Transfer tokens to Module to burn + * @param _value The number of tokens to redeem + */ + function transferToRedeem(uint256 _value) public { + require(ISecurityToken(securityToken).transferFrom(msg.sender, address(this), _value), "Insufficient funds"); + tokenToRedeem[msg.sender] = _value; + } + + /** + * @notice use to redeem tokens by the module + * @param _value The number of tokens to redeem + */ + function redeemTokenByOwner(uint256 _value) public { + require(tokenToRedeem[msg.sender] >= _value); + tokenToRedeem[msg.sender] = tokenToRedeem[msg.sender].sub(_value); + redeemedTokens[msg.sender] = redeemedTokens[msg.sender].add(_value); + ISecurityToken(securityToken).burnWithData(_value, ""); + emit RedeemedTokenByOwner(msg.sender, address(this), _value, now); + } + +} diff --git a/contracts/mocks/MockWrongTypeFactory.sol b/contracts/mocks/MockWrongTypeFactory.sol new file mode 100644 index 000000000..f04a3a2de --- /dev/null +++ b/contracts/mocks/MockWrongTypeFactory.sol @@ -0,0 +1,31 @@ +pragma solidity ^0.4.24; + +import "./MockBurnFactory.sol"; +import "../modules/ModuleFactory.sol"; +import "../libraries/Util.sol"; + +/** + * @title Mock Contract Not fit for production environment + */ + +contract MockWrongTypeFactory is MockBurnFactory { + + /** + * @notice Constructor + * @param _polyAddress Address of the polytoken + */ + constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public + MockBurnFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + { + } + + /** + * @notice Type of the Module factory + */ + function getTypes() external view returns(uint8[]) { + uint8[] memory types = new uint8[](1); + types[0] = 4; + return types; + } + +} diff --git a/contracts/mocks/TestSTOFactory.sol b/contracts/mocks/TestSTOFactory.sol index 85c32f2f9..eb26bd922 100644 --- a/contracts/mocks/TestSTOFactory.sol +++ b/contracts/mocks/TestSTOFactory.sol @@ -1,17 +1,15 @@ pragma solidity ^0.4.24; -import "../modules/STO/DummySTO.sol"; -import "../modules/ModuleFactory.sol"; -import "../libraries/Util.sol"; +import "../modules/STO/DummySTOFactory.sol"; -contract TestSTOFactory is ModuleFactory { +contract TestSTOFactory is DummySTOFactory { /** * @notice Constructor * @param _polyAddress Address of the polytoken */ constructor (address _polyAddress, uint256 _setupCost, uint256 _usageCost, uint256 _subscriptionCost) public - ModuleFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) + DummySTOFactory(_polyAddress, _setupCost, _usageCost, _subscriptionCost) { version = "1.0.0"; name = "TestSTO"; @@ -21,66 +19,6 @@ contract TestSTOFactory is ModuleFactory { compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); } - /** - * @notice used to launch the Module with the help of factory - * @param _data Data used for the intialization of the module factory variables - * @return address Contract address of the Module - */ - function deploy(bytes _data) external returns(address) { - if(setupCost > 0) - require(polyToken.transferFrom(msg.sender, owner, setupCost), "Failed transferFrom because of sufficent Allowance is not provided"); - //Check valid bytes - can only call module init function - DummySTO dummySTO = new DummySTO(msg.sender, address(polyToken)); - //Checks that _data is valid (not calling anything it shouldn't) - require(Util.getSig(_data) == dummySTO.getInitFunction(), "Provided data is not valid"); - require(address(dummySTO).call(_data), "Un-successfull call"); - return address(dummySTO); - } - - /** - * @notice Type of the Module factory - */ - function getTypes() external view returns(uint8[]) { - uint8[] memory res = new uint8[](1); - res[0] = 3; - return res; - } - - /** - * @notice Get the name of the Module - */ - function getName() external view returns(bytes32) { - return name; - } - - /** - * @notice Get the description of the Module - */ - function getDescription() external view returns(string) { - return description; - } - - /** - * @notice Get the title of the Module - */ - function getTitle() external view returns(string) { - return title; - } - - /** - * @notice Get the version of the Module - */ - function getVersion() external view returns(string) { - return version; - } - - /** - * @notice Get the setup cost of the module - */ - function getSetupCost() external view returns (uint256) { - return setupCost; - } - /** * @notice Returns the instructions associated with the module */ diff --git a/contracts/modules/Burn/TrackedRedemption.sol b/contracts/modules/Burn/TrackedRedemption.sol index f6211a140..60745f778 100644 --- a/contracts/modules/Burn/TrackedRedemption.sol +++ b/contracts/modules/Burn/TrackedRedemption.sol @@ -41,7 +41,7 @@ contract TrackedRedemption is IBurn, Module { redeemedTokens[msg.sender] = redeemedTokens[msg.sender].add(_value); emit Redeemed(msg.sender, _value, now); } - + /** * @notice Return the permissions flag that are associated with CountTransferManager */ diff --git a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol index aa3810747..1dcc9f4cd 100644 --- a/contracts/modules/TransferManager/ManualApprovalTransferManager.sol +++ b/contracts/modules/TransferManager/ManualApprovalTransferManager.sol @@ -129,7 +129,7 @@ contract ManualApprovalTransferManager is ITransferManager { require(_from != address(0), "Invalid from address"); require(_to != address(0), "Invalid to address"); require(_expiryTime > now, "Invalid expiry time"); - require(manualApprovals[_from][_to].expiryTime == 0, "Blocking already exists"); + require(manualBlockings[_from][_to].expiryTime == 0, "Blocking already exists"); manualBlockings[_from][_to] = ManualBlocking(_expiryTime); emit AddManualBlocking(_from, _to, _expiryTime, msg.sender); } diff --git a/contracts/proxy/OwnedUpgradeabilityProxy.sol b/contracts/proxy/OwnedUpgradeabilityProxy.sol index e1890a243..81a634ec8 100644 --- a/contracts/proxy/OwnedUpgradeabilityProxy.sol +++ b/contracts/proxy/OwnedUpgradeabilityProxy.sol @@ -80,7 +80,7 @@ contract OwnedUpgradeabilityProxy is UpgradeabilityProxy { * @return address of the current implementation */ function implementation() external ifOwner returns (address) { - _implementation(); + return _implementation(); } /** diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index dde865fa8..1d2b165f5 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -341,13 +341,16 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr return modules[_type]; } - /** - * @notice allows the owner to withdraw unspent POLY stored by them on the ST. + /** + * @notice allows the owner to withdraw unspent POLY stored by them on the ST or any ERC20 token. * @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee. + * @param _tokenContract Address of the ERC20Basic compliance token * @param _value amount of POLY to withdraw */ - function withdrawPoly(uint256 _value) external onlyOwner { - require(ERC20(polyToken).transfer(owner, _value), "Insufficient balance"); + function withdrawERC20(address _tokenContract, uint256 _value) external onlyOwner { + require(_tokenContract != address(0)); + IERC20 token = IERC20(_tokenContract); + require(token.transfer(owner, _value)); } /** @@ -429,7 +432,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice freezes transfers */ function freezeTransfers() external onlyOwner { - require(!transfersFrozen, "transfers already frozen"); + require(!transfersFrozen, "Already frozen"); transfersFrozen = true; emit FreezeTransfers(true, now); } @@ -438,7 +441,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice unfreeze transfers */ function unfreezeTransfers() external onlyOwner { - require(transfersFrozen, "transfer are not fronzen"); + require(transfersFrozen, "Not frozen"); transfersFrozen = false; emit FreezeTransfers(false, now); } @@ -730,7 +733,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _controller address of the controller */ function setController(address _controller) public onlyOwner { - require(!controllerDisabled,"Controller functions are disabled"); + require(!controllerDisabled,"Controller disabled"); emit SetController(controller, _controller); controller = _controller; } @@ -740,7 +743,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @dev enabled via feature switch "disableControllerAllowed" */ function disableController() external isEnabled("disableControllerAllowed") onlyOwner { - require(!controllerDisabled,"Controller functions are disabled"); + require(!controllerDisabled,"Controller disabled"); controllerDisabled = true; delete controller; emit DisableController(now); diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 33fc5f6a6..ff80f1025 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -88,6 +88,7 @@ contract("CappedSTO", accounts => { const cap = web3.utils.toWei("10000"); const rate = 1000; const E_fundRaiseType = 0; + const address_zero = "0x0000000000000000000000000000000000000000"; let startTime_POLY1; let endTime_POLY1; @@ -136,7 +137,7 @@ contract("CappedSTO", accounts => { assert.notEqual( I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "CappedSTOFactory contract was not deployed" ); @@ -197,7 +198,7 @@ contract("CappedSTO", accounts => { it("Should mint the tokens before attaching the STO", async () => { await catchRevert( - I_SecurityToken_ETH.mint("0x0000000000000000000000000000000000000000", web3.utils.toWei("1"), { from: token_owner }) + I_SecurityToken_ETH.mint(address_zero, web3.utils.toWei("1"), { from: token_owner }) ); }); @@ -221,6 +222,24 @@ contract("CappedSTO", accounts => { await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); + it("Should fail to launch the STO due funds reciever account 0x", async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], address_zero]); + + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); + + it("Should fail to launch the STO due to raise type of 0 length", async () => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [], account_fundsReceiver]); + + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); + it("Should fail to launch the STO due to startTime > endTime", async () => { let bytesSTO = encodeModuleCall(STOParameters, [ Math.floor(Date.now() / 1000 + 100000), @@ -242,6 +261,13 @@ contract("CappedSTO", accounts => { await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); }); + it("Should fail to launch the STO due to different value incompare to getInitFunction", async() => { + let startTime = latestTime() + duration.days(1); + let endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(['uint256', 'uint256', 'uint256'], [startTime, endTime, 0, ]); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner })); + }); + it("Should successfully attach the STO module to the security token", async () => { startTime_ETH1 = latestTime() + duration.days(1); endTime_ETH1 = startTime_ETH1 + duration.days(30); @@ -259,6 +285,12 @@ contract("CappedSTO", accounts => { assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); I_CappedSTO_Array_ETH.push(CappedSTO.at(tx.logs[3].args._module)); }); + + it("Should call the configure function -- fail because of the bad owner", async()=> { + await catchRevert( + I_CappedSTO_Array_ETH[0].configure(startTime_ETH1, endTime_ETH1, cap, rate, [E_fundRaiseType], account_fundsReceiver, {from: account_polymath }) + ); + }) }); describe("verify the data of STO", async () => { @@ -329,8 +361,7 @@ contract("CappedSTO", accounts => { // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist(account_investor1, fromTime, toTime, expiryTime, true, { - from: account_issuer, - gas: 500000 + from: account_issuer }); assert.equal(tx.logs[0].args._investor, account_investor1, "Failed in adding the investor in whitelist"); @@ -346,10 +377,9 @@ contract("CappedSTO", accounts => { }); assert.equal((await I_CappedSTO_Array_ETH[0].getRaised.call(ETH)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1); - assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 1); - assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); + assert.equal((await I_CappedSTO_Array_ETH[0].getTokensSold.call()).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); }); it("Verification of the event Token Purchase", async () => { @@ -359,6 +389,14 @@ contract("CappedSTO", accounts => { assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000, "Wrong No. token get dilivered"); }); + it("Should fail to buy the tokens -- Because fundRaiseType is ETH not POLY", async ()=> { + await I_PolyToken.getTokens(web3.utils.toWei("500"), account_investor1); + await I_PolyToken.approve(I_CappedSTO_Array_ETH[0].address, web3.utils.toWei("500"), {from: account_investor1}); + await catchRevert( + I_CappedSTO_Array_ETH[0].buyTokensWithPoly(web3.utils.toWei("500"), {from: account_investor1}) + ); + }) + it("Should pause the STO -- Failed due to wrong msg.sender", async () => { await catchRevert(I_CappedSTO_Array_ETH[0].pause({ from: account_investor1 })); }); @@ -407,8 +445,7 @@ contract("CappedSTO", accounts => { expiryTime, true, { - from: account_issuer, - gas: 500000 + from: account_issuer } ); @@ -427,7 +464,7 @@ contract("CappedSTO", accounts => { assert.equal(await I_CappedSTO_Array_ETH[0].investorCount.call(), 2); assert.equal((await I_SecurityToken_ETH.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 9000); - await catchRevert(I_CappedSTO_Array_ETH[0].buyTokens(account_investor2, { value: web3.utils.toWei("100") })); + await catchRevert(I_CappedSTO_Array_ETH[0].buyTokens(account_investor2, { value: web3.utils.toWei("81") })); }); it("Should fundRaised value equal to the raised value in the funds receiver wallet", async () => { @@ -458,7 +495,7 @@ contract("CappedSTO", accounts => { await I_PolyToken.getTokens(value, account_investor1); await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); - await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20("0x0000000000000000000000000000000000000000", { from: token_owner })); + await catchRevert(I_CappedSTO_Array_ETH[0].reclaimERC20(address_zero, { from: token_owner })); }); it("Should successfully reclaim POLY", async () => { @@ -471,7 +508,7 @@ contract("CappedSTO", accounts => { await I_PolyToken.transfer(I_CappedSTO_Array_ETH[0].address, value, { from: account_investor1 }); await I_CappedSTO_Array_ETH[0].reclaimERC20(I_PolyToken.address, { from: token_owner }); assert.equal( - (await I_PolyToken.balanceOf(account_investor3)).toNumber(), + (await I_PolyToken.balanceOf(account_investor1)).toNumber(), initInvestorBalance.toNumber(), "tokens are not transfered out from investor account" ); @@ -553,6 +590,12 @@ contract("CappedSTO", accounts => { assert.equal(allow, true, "allowBeneficialInvestments should be true"); }); + it("Should allow non-matching beneficiary -- failed because it is already active", async () => { + await catchRevert( + I_CappedSTO_Array_ETH[1].changeAllowBeneficialInvestments(true, { from: account_issuer }) + ); + }); + it("Should invest in second STO", async () => { await I_CappedSTO_Array_ETH[1].buyTokens(account_investor3, { from: account_issuer, value: web3.utils.toWei("1", "ether") }); @@ -686,7 +729,7 @@ contract("CappedSTO", accounts => { blockNo = latestBlock(); assert.equal( (await I_PolyToken.balanceOf(account_investor1)).dividedBy(new BigNumber(10).pow(18)).toNumber(), - 10000, + 10500, "Tokens are not transfered properly" ); @@ -704,8 +747,7 @@ contract("CappedSTO", accounts => { // buyTokensWithPoly transaction await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { - from: account_investor1, - gas: 6000000 + from: account_investor1 }); assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 1000); @@ -725,6 +767,33 @@ contract("CappedSTO", accounts => { assert.equal(log.args.amount.dividedBy(new BigNumber(10).pow(18)).toNumber(), 5000, "Wrong No. token get dilivered"); }); + it("Should failed to buy tokens -- because fundraisetype is POLY not ETH", async() => { + await catchRevert( + // Fallback transaction + web3.eth.sendTransaction({ + from: account_investor1, + to: I_CappedSTO_Array_POLY[0].address, + gas: 2100000, + value: web3.utils.toWei("2", "ether") + }) + ); + }); + + it("Should fail in buying tokens because buying is paused", async() => { + await I_CappedSTO_Array_POLY[0].pause({ from: account_issuer }); + await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 }); + + // buyTokensWithPoly transaction + await catchRevert( + I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { + from: account_investor1, + gas: 6000000 + }) + ); + await I_CappedSTO_Array_POLY[0].unpause({ from: account_issuer }); + }); + + it("Should restrict to buy tokens after hiting the cap in second tx first tx pass", async () => { let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor2, @@ -745,7 +814,7 @@ contract("CappedSTO", accounts => { await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 9000 * Math.pow(10, 18), { from: account_investor2 }); // buyTokensWithPoly transaction - await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(9000 * Math.pow(10, 18), { from: account_investor2, gas: 6000000 }); + await I_CappedSTO_Array_POLY[0].buyTokensWithPoly(9000 * Math.pow(10, 18), { from: account_investor2 }); assert.equal((await I_CappedSTO_Array_POLY[0].getRaised.call(POLY)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 10000); @@ -757,7 +826,7 @@ contract("CappedSTO", accounts => { ); await I_PolyToken.approve(I_CappedSTO_Array_POLY[0].address, 1000 * Math.pow(10, 18), { from: account_investor1 }); await catchRevert( - I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { from: account_investor1, gas: 6000000 }) + I_CappedSTO_Array_POLY[0].buyTokensWithPoly(1000 * Math.pow(10, 18), { from: account_investor1 }) ); }); @@ -797,6 +866,7 @@ contract("CappedSTO", accounts => { ); let tags = await I_CappedSTOFactory.getTags.call(); assert.equal(web3.utils.hexToString(tags[0]), "Capped"); + assert.equal(await I_CappedSTOFactory.getVersion.call(), "1.0.0"); }); it("Should fail to change the title -- bad owner", async () => { diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 3bf785a5d..6db725c74 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -249,7 +249,33 @@ contract("CountTransferManager", accounts => { assert.equal((await I_SecurityToken.balanceOf(account_investor2)).toNumber(), web3.utils.toWei("2", "ether")); }); + it("Should able to buy some more tokens (more than 2 hoders) -- because CountTransferManager is paused", async() => { + await I_CountTransferManager.pause({from: account_issuer }); + let snapId = await takeSnapshot(); + let tx = await I_GeneralTransferManager.modifyWhitelist( + account_investor3, + latestTime(), + latestTime(), + latestTime() + duration.days(10), + true, + { + from: account_issuer, + gas: 500000 + } + ); + + assert.equal( + tx.logs[0].args._investor.toLowerCase(), + account_investor3.toLowerCase(), + "Failed in adding the investor in whitelist" + ); + + await I_SecurityToken.mint(account_investor3, web3.utils.toWei("3", "ether"), { from: token_owner }) + await revertToSnapshot(snapId); + }) + it("Should fail to buy some more tokens (more than 2 holders)", async () => { + await I_CountTransferManager.unpause({from: account_issuer }); // Add the Investor in to the whitelist let tx = await I_GeneralTransferManager.modifyWhitelist( account_investor3, @@ -349,5 +375,79 @@ contract("CountTransferManager", accounts => { assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ""), "Count"); }); }); + + describe("Test cases for the ModuleFactory", async() => { + it("Should successfully change the SetupCost -- fail beacuse of bad owner", async() => { + await catchRevert( + I_CountTransferManagerFactory.changeFactorySetupFee(web3.utils.toWei("500"), {from: account_investor3}) + ); + }); + + it("Should successfully change the setupCost", async() => { + await I_CountTransferManagerFactory.changeFactorySetupFee(web3.utils.toWei("800"), { from: account_polymath }); + assert.equal(await I_CountTransferManagerFactory.getSetupCost.call(), web3.utils.toWei("800")); + }) + + it("Should successfully change the usage fee -- fail beacuse of bad owner", async() => { + await catchRevert( + I_CountTransferManagerFactory.changeFactoryUsageFee(web3.utils.toWei("500"), {from: account_investor3}) + ); + }); + + it("Should successfully change the usage fee", async() => { + await I_CountTransferManagerFactory.changeFactoryUsageFee(web3.utils.toWei("800"), { from: account_polymath }); + assert.equal(await I_CountTransferManagerFactory.usageCost.call(), web3.utils.toWei("800")); + }); + + it("Should successfully change the subscription fee -- fail beacuse of bad owner", async() => { + await catchRevert( + I_CountTransferManagerFactory.changeFactorySubscriptionFee(web3.utils.toWei("500"), {from: account_investor3}) + ); + }); + + it("Should successfully change the subscription fee", async() => { + await I_CountTransferManagerFactory.changeFactorySubscriptionFee(web3.utils.toWei("800"), { from: account_polymath }); + assert.equal(await I_CountTransferManagerFactory.monthlySubscriptionCost.call(), web3.utils.toWei("800")); + }); + + it("Should successfully change the version of the factory -- failed because of bad owner", async() => { + await catchRevert( + I_CountTransferManagerFactory.changeVersion("5.0.0", {from: account_investor3}) + ); + }); + + it("Should successfully change the version of the fatory -- failed because of the 0 string", async() => { + await catchRevert( + I_CountTransferManagerFactory.changeVersion("", {from: account_polymath}) + ); + }); + + it("Should successfully change the version of the fatory", async() => { + await I_CountTransferManagerFactory.changeVersion("5.0.0", {from: account_polymath}); + assert.equal(await I_CountTransferManagerFactory.getVersion.call(), "5.0.0"); + }); + }) + + describe("Test case for the changeSTVersionBounds", async() => { + it("Should successfully change the version bounds -- failed because of the non permitted bound type", async() => { + await catchRevert( + I_CountTransferManagerFactory.changeSTVersionBounds("middleType", [1,2,3], {from: account_polymath}) + ); + }) + + it("Should successfully change the version bound --failed because the new version length < 3", async()=> { + await catchRevert( + I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1,2], {from: account_polymath}) + ); + }) + + it("Should successfully change the version bound", async()=> { + await I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1,2,1], {from: account_polymath}); + await I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1,4,9], {from: account_polymath}); + await catchRevert( + I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1,0,0], {from: account_polymath}) + ); + }) + }) }); }); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 0cf090030..eb22406c8 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -1,22 +1,21 @@ -import latestTime from "./helpers/latestTime"; -import { signData } from "./helpers/signData"; -import { pk } from "./helpers/testprivateKey"; -import { duration, ensureException, promisifyLogWatch, latestBlock } from "./helpers/utils"; -import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; -import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; +import latestTime from './helpers/latestTime'; +import {signData} from './helpers/signData'; +import { pk } from './helpers/testprivateKey'; +import { duration, promisifyLogWatch, latestBlock } from './helpers/utils'; +import { takeSnapshot, increaseTime, revertToSnapshot } from './helpers/time'; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployGPMAndVerifyed } from "./helpers/createInstances"; -const DummySTO = artifacts.require("./DummySTO.sol"); -const SecurityToken = artifacts.require("./SecurityToken.sol"); -const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); -const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const SecurityToken = artifacts.require('./SecurityToken.sol'); +const GeneralTransferManager = artifacts.require('./GeneralTransferManager'); +const GeneralPermissionManager = artifacts.require('./GeneralPermissionManager'); -const Web3 = require("web3"); -const BigNumber = require("bignumber.js"); -const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port +const Web3 = require('web3'); +const BigNumber = require('bignumber.js'); +const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) // Hardcoded development port + +contract('GeneralPermissionManager', accounts => { -contract("GeneralPermissionManager", accounts => { // Accounts Variable declaration let account_polymath; let account_issuer; @@ -53,7 +52,6 @@ contract("GeneralPermissionManager", accounts => { let I_SecurityToken; let I_MRProxied; let I_STRProxied; - let I_DummySTO; let I_PolyToken; let I_PolymathRegistry; @@ -73,16 +71,7 @@ contract("GeneralPermissionManager", accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); - // Dummy STO details - const startTime = latestTime() + duration.seconds(5000); // Start time will be 5000 seconds more than the latest time - const endTime = startTime + duration.days(80); // Add 80 days more - const cap = web3.utils.toWei("10", "ether"); - const someString = "A string which is not used"; - const STOParameters = ["uint256", "uint256", "uint256", "string"]; - - let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, someString]); - - before(async () => { + before(async() => { // Accounts setup account_polymath = accounts[0]; account_issuer = accounts[1]; @@ -112,14 +101,11 @@ contract("GeneralPermissionManager", accounts => { I_SecurityTokenRegistryProxy, I_STRProxied ] = instances; - // STEP 5: Deploy the GeneralDelegateManagerFactory [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); // STEP 6: Deploy the GeneralDelegateManagerFactory - [P_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500", "ether")); - // STEP 7: Deploy the DummySTOFactory - [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [P_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); // Printing all the contract addresses console.log(` @@ -134,8 +120,6 @@ contract("GeneralPermissionManager", accounts => { STFactory: ${I_STFactory.address} GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - DummySTOFactory: ${I_DummySTOFactory.address} ----------------------------------------------------------------------------- `); }); @@ -170,12 +154,11 @@ contract("GeneralPermissionManager", accounts => { I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); - it("Should successfully attach the General permission manager factory with the security token", async () => { + it("Should successfully attach the General permission manager factory with the security token -- failed because Token is not paid", async () => { + let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("500", "ether"), token_owner); await catchRevert( - I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { - from: token_owner - }) + I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", web3.utils.toWei("500", "ether"), 0, { from: token_owner }) ); }); @@ -218,27 +201,22 @@ contract("GeneralPermissionManager", accounts => { assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ""), 0); }); - it("Should fail in adding the permission to the delegate --msg.sender doesn't have permission", async () => { - await catchRevert(I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1 })); - }); - - it("Should fail to provide the permission-- because delegate is not yet added", async () => { - await catchRevert( - I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { - from: token_owner - }) - ); - }); - it("Should fail in adding the delegate -- msg.sender doesn't have permission", async() => { + let errorThrown = false; await catchRevert( I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_investor1}) ); }); it("Should fail in adding the delegate -- no delegate details provided", async() => { + catchRevert( + I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: token_owner }) + ); + }); + + it("Should fail to provide the permission -- because delegate is not yet added", async() => { await catchRevert( - I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: account_investor1}) + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}) ); }); @@ -247,12 +225,16 @@ contract("GeneralPermissionManager", accounts => { assert.equal(tx.logs[0].args._delegate, account_delegate); }); - it("Should fail to provide the permission", async () => { + it("Should successfully add the delegate -- failed because trying to add the already present delegate", async() => { await catchRevert( - I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, { - from: account_investor1 - }) + I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner}) ); + }) + + it("Should fail to provide the permission -- because msg.sender doesn't have permission", async() => { + await catchRevert( + I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: account_investor1}) + ); }); it("Should check the permission", async () => { @@ -293,12 +275,17 @@ contract("GeneralPermissionManager", accounts => { it("Should return all delegates", async() => { await I_GeneralPermissionManager.addDelegate(account_delegate2, delegateDetails, { from: token_owner}); let tx = await I_GeneralPermissionManager.getAllDelegates.call(); - console.log(tx); assert.equal(tx.length, 2); assert.equal(tx[0], account_delegate); assert.equal(tx[1], account_delegate2); }); + it("Should check is delegate for 0x address - failed 0x address is not allowed", async() => { + await catchRevert( + I_GeneralPermissionManager.checkDelegate.call("0x0000000000000000000000000000000000000000000000000") + ); + }); + it("Should return false when check is delegate - because user is not a delegate", async() => { assert.equal(await I_GeneralPermissionManager.checkDelegate.call(account_investor1), false); }); @@ -308,9 +295,32 @@ contract("GeneralPermissionManager", accounts => { }); - it("Should provide the permission in bulk", async() => { + it("Should successfully provide the permissions in batch -- failed because of array length is 0", async() => { await I_GeneralPermissionManager.addDelegate(account_delegate3, delegateDetails, { from: token_owner}); + await catchRevert( + I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [], ["WHITELIST","CHANGE_PERMISSION"], [true, true], {from: token_owner}) + ); + }); + + it("Should successfully provide the permissions in batch -- failed because of perm array length is 0", async() => { + await catchRevert( + I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], [], [true, true], {from: token_owner}) + ); + }); + + it("Should successfully provide the permissions in batch -- failed because mismatch in arrays length", async() => { + await catchRevert( + I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [I_GeneralTransferManager.address], ["WHITELIST","CHANGE_PERMISSION"], [true, true], {from: token_owner}) + ); + }); + + it("Should successfully provide the permissions in batch -- failed because mismatch in arrays length", async() => { + await catchRevert( + I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], ["WHITELIST","CHANGE_PERMISSION"], [true], {from: token_owner}) + ); + }); + it("Should successfully provide the permissions in batch", async() => { let tx = await I_GeneralPermissionManager.changePermissionMulti(account_delegate3, [I_GeneralTransferManager.address, I_GeneralPermissionManager.address], ["WHITELIST","CHANGE_PERMISSION"], [true, true], {from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate3); @@ -318,27 +328,26 @@ contract("GeneralPermissionManager", accounts => { assert.isTrue(await I_GeneralPermissionManager.checkPermission.call(account_delegate3, I_GeneralPermissionManager.address, "CHANGE_PERMISSION")); }); - it("Should provide all delegates with specified permission", async() => { - await I_GeneralPermissionManager.changePermission(account_delegate2, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}); - let tx = await I_GeneralPermissionManager.getAllDelegatesWithPerm.call(I_GeneralTransferManager.address, "WHITELIST"); - // console.log(tx); assert.equal(tx.length, 3); assert.equal(tx[0], account_delegate); assert.equal(tx[1], account_delegate2); }); + it("Should get all delegates for the permission manager", async() => { + let tx = await I_GeneralPermissionManager.getAllDelegatesWithPerm.call(I_GeneralPermissionManager.address, "CHANGE_PERMISSION"); + assert.equal(tx.length, 1); + assert.equal(tx[0], account_delegate3); + }) + it("Should return all modules and all permission", async() => { - let tx = await I_GeneralPermissionManager.getAllModulesAndPermsFromTypes.call(account_delegate3, [2,1], I_SecurityToken.address); - console.log (tx); assert.equal(tx[0][0], I_GeneralTransferManager.address); assert.equal(tx[1][0], "0x57484954454c4953540000000000000000000000000000000000000000000000"); assert.equal(tx[0][1], I_GeneralPermissionManager.address); assert.equal(tx[1][1], "0x4348414e47455f5045524d495353494f4e000000000000000000000000000000"); - }); }); @@ -370,5 +379,10 @@ contract("GeneralPermissionManager", accounts => { let tags = await I_GeneralPermissionManagerFactory.getTags.call(); assert.equal(tags.length, 0); }); + + it("Should ge the version of the factory", async() => { + let version = await I_GeneralPermissionManagerFactory.getVersion.call(); + assert.equal(version, "1.0.0"); + }) }); }); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 6f1272ded..c40809d8b 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -5,7 +5,7 @@ import { signData } from "./helpers/signData"; import { pk } from "./helpers/testprivateKey"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployGPMAndVerifyed, deployDummySTOAndVerifyed, deployGTMAndVerifyed } from "./helpers/createInstances"; const DummySTO = artifacts.require("./DummySTO.sol"); @@ -49,6 +49,7 @@ contract("GeneralTransferManager", accounts => { let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_DummySTOFactory; + let P_DummySTOFactory; let I_STFactory; let I_SecurityToken; let I_STRProxied; @@ -56,6 +57,7 @@ contract("GeneralTransferManager", accounts => { let I_DummySTO; let I_PolyToken; let I_PolymathRegistry; + let P_GeneralTransferManagerFactory; // SecurityToken Details const name = "Team"; @@ -113,7 +115,9 @@ contract("GeneralTransferManager", accounts => { ] = instances; [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [P_GeneralTransferManagerFactory] = await deployGTMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); [I_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [P_DummySTOFactory] = await deployDummySTOAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); // Printing all the contract addresses console.log(` @@ -164,6 +168,19 @@ contract("GeneralTransferManager", accounts => { I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); + it("Should attach the paid GTM -- failed because of no tokens", async() => { + await catchRevert( + I_SecurityToken.addModule(P_GeneralTransferManagerFactory.address, "", web3.utils.toWei("500"), 0, {from: account_issuer}) + ); + }) + + it("Should attach the paid GTM", async() => { + let snap_id = await takeSnapshot(); + await I_PolyToken.getTokens(web3.utils.toWei("500"), I_SecurityToken.address); + await I_SecurityToken.addModule(P_GeneralTransferManagerFactory.address, "", web3.utils.toWei("500"), 0, {from: account_issuer}); + await revertToSnapshot(snap_id); + }) + it("Should whitelist the affiliates before the STO attached", async () => { let tx = await I_GeneralTransferManager.modifyWhitelistMulti( [account_affiliates1, account_affiliates2], @@ -189,6 +206,49 @@ contract("GeneralTransferManager", accounts => { assert.equal((await I_SecurityToken.balanceOf.call(account_affiliates2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); }); + + it("Should successfully attach the STO factory with the security token -- failed because of no tokens", async () => { + let bytesSTO = encodeModuleCall(STOParameters, [ + latestTime() + duration.seconds(1000), + latestTime() + duration.days(40), + cap, + someString + ]); + await catchRevert( + I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, web3.utils.toWei("500"), 0, { from: token_owner }) + ); + }); + + it("Should successfully attach the STO factory with the security token", async () => { + let snap_id = await takeSnapshot(); + let bytesSTO = encodeModuleCall(STOParameters, [ + latestTime() + duration.seconds(1000), + latestTime() + duration.days(40), + cap, + someString + ]); + await I_PolyToken.getTokens(web3.utils.toWei("500"), I_SecurityToken.address); + const tx = await I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, web3.utils.toWei("500"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._types[0].toNumber(), stoKey, "DummySTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), + "DummySTO", + "DummySTOFactory module was not added" + ); + I_DummySTO = DummySTO.at(tx.logs[3].args._module); + await revertToSnapshot(snap_id); + }); + + it("Should successfully attach the STO factory with the security token - invalid data", async () => { + let bytesSTO = encodeModuleCall(['uint256', 'string'], [ + latestTime() + duration.seconds(1000), + someString + ]); + await catchRevert( + I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, 0, 0, { from: token_owner }) + ); + }); + it("Should successfully attach the STO factory with the security token", async () => { let bytesSTO = encodeModuleCall(STOParameters, [ latestTime() + duration.seconds(1000), @@ -257,6 +317,24 @@ contract("GeneralTransferManager", accounts => { await catchRevert(I_DummySTO.generateTokens(account_affiliates1, web3.utils.toWei("1", "ether"), { from: token_owner })); }); + it("Should fail in buying the tokens from the STO -- because amount is 0", async() => { + await catchRevert( + I_DummySTO.generateTokens(account_investor1, 0, { from: token_owner }) + ); + }); + + it("Should fail in buying the tokens from the STO -- because STO is paused", async() => { + await I_DummySTO.pause({from: account_issuer }); + await catchRevert(I_DummySTO.generateTokens(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner })); + // Reverting the changes releated to pause + await I_DummySTO.unpause({from: account_issuer }); + }); + + it("Should buy more tokens from the STO to investor1", async() => { + await I_DummySTO.generateTokens(account_investor1, web3.utils.toWei("1", "ether"), { from: token_owner }); + assert.equal((await I_SecurityToken.balanceOf(account_investor1)).toNumber(), web3.utils.toWei("2", "ether")); + }); + it("Should fail in investing the money in STO -- expiry limit reached", async () => { await increaseTime(duration.days(10)); @@ -478,7 +556,7 @@ contract("GeneralTransferManager", accounts => { it("Should set a budget for the GeneralTransferManager", async () => { await I_SecurityToken.changeModuleBudget(I_GeneralTransferManager.address, 10 * Math.pow(10, 18), { from: token_owner }); - await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: account_polymath })); + await catchRevert(I_GeneralTransferManager.takeFee(web3.utils.toWei("1", "ether"), { from: token_owner })); await I_PolyToken.getTokens(10 * Math.pow(10, 18), token_owner); await I_PolyToken.transfer(I_SecurityToken.address, 10 * Math.pow(10, 18), { from: token_owner }); }); @@ -646,6 +724,7 @@ contract("GeneralTransferManager", accounts => { "Allows an issuer to maintain a time based whitelist of authorised token holders.Addresses are added via modifyWhitelist, and take a fromTime (the time from which they can send tokens) and a toTime (the time from which they can receive tokens). There are additional flags, allowAllWhitelistIssuances, allowAllWhitelistTransfers & allowAllTransfers which allow you to set corresponding contract level behaviour. Init function takes no parameters.", "Wrong Module added" ); + assert.equal(await I_GeneralPermissionManagerFactory.getVersion.call(), "1.0.0"); }); it("Should get the tags of the factory", async () => { @@ -672,6 +751,11 @@ contract("GeneralTransferManager", accounts => { let tags = await I_DummySTOFactory.getTags.call(); assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ""), "Dummy"); }); + + it("Should get the version of factory", async() => { + let version = await I_DummySTOFactory.getVersion.call(); + assert.equal(version, "1.0.0"); + }); }); describe("Test cases for the get functions of the dummy sto", async () => { @@ -684,12 +768,16 @@ contract("GeneralTransferManager", accounts => { }); it("Should get the investors", async () => { - assert.equal((await I_DummySTO.investorCount.call()).toNumber(), 2); + assert.equal((await I_DummySTO.getNumberInvestors.call()).toNumber(), 2); }); it("Should get the listed permissions", async () => { let tx = await I_DummySTO.getPermissions.call(); assert.equal(web3.utils.toAscii(tx[0]).replace(/\u0000/g, ""), "ADMIN"); }); + + it("Should get the amount of tokens sold", async() => { + assert.equal(await I_DummySTO.getTokensSold.call(), 0); + }) }); }); diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 82a77e42a..f72ab54e3 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -27,6 +27,8 @@ const PreSaleSTOFactory = artifacts.require("./PreSaleSTOFactory.sol"); const PolyToken = artifacts.require("./PolyToken.sol"); const PolyTokenFaucet = artifacts.require("./PolyTokenFaucet.sol"); const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); +const MockBurnFactory = artifacts.require("./MockBurnFactory.sol"); +const MockWrongTypeFactory = artifacts.require("./MockWrongTypeFactory.sol"); const Web3 = require("web3"); const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); // Hardcoded development port @@ -35,6 +37,8 @@ const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); let I_USDTieredSTOProxyFactory; let I_USDTieredSTOFactory; let I_TrackedRedemptionFactory; +let I_MockBurnFactory; +let I_MockWrongTypeBurnFactory; let I_SingleTradeVolumeRestrictionManagerFactory; let I_ManualApprovalTransferManagerFactory; let I_VolumeRestrictionTransferManagerFactory; @@ -378,7 +382,31 @@ export async function deployRedemptionAndVerifyed(accountPolymath, MRProxyInstan } +export async function deployMockRedemptionAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_MockBurnFactory = await MockBurnFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + assert.notEqual( + I_MockBurnFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "MockBurnfactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_MockBurnFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_MockBurnFactory); +} + +export async function deployMockWrongTypeRedemptionAndVerifyed(accountPolymath, MRProxyInstance, polyToken, setupCost) { + I_MockWrongTypeBurnFactory = await MockWrongTypeFactory.new(polyToken, setupCost, 0, 0, { from: accountPolymath }); + + assert.notEqual( + I_MockWrongTypeBurnFactory.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "MockWrongTypeBurnFactory contract was not deployed" + ); + + await registerAndVerifyByMR(I_MockWrongTypeBurnFactory.address, accountPolymath, MRProxyInstance); + return new Array(I_MockWrongTypeBurnFactory); +} diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 2087e2bbe..ac1fcdd37 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -63,6 +63,7 @@ contract("Issuance", accounts => { const transferManagerKey = 2; const stoKey = 3; const budget = 0; + const address_zero = "0x0000000000000000000000000000000000000000"; // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); @@ -171,7 +172,7 @@ contract("Issuance", accounts => { assert.notEqual( I_CappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "CappedSTOFactory contract was not deployed" ); diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 61472e4ff..0a1346f31 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -302,12 +302,15 @@ contract("ManualApprovalTransferManager", accounts => { account_investor3.toLowerCase(), "Failed in adding the investor in whitelist" ); - + // Pause at the transferManager level + await I_ManualApprovalTransferManager.pause({from: token_owner}); // Add the Investor in to the whitelist // Mint some tokens await I_SecurityToken.mint(account_investor3, web3.utils.toWei("1", "ether"), { from: token_owner }); assert.equal((await I_SecurityToken.balanceOf(account_investor3)).toNumber(), web3.utils.toWei("1", "ether")); + // Unpause at the transferManager level + await I_ManualApprovalTransferManager.unpause({from: token_owner}); }); it("Should still be able to transfer between existing token holders", async () => { @@ -364,6 +367,18 @@ contract("ManualApprovalTransferManager", accounts => { ); }); + it("Should fail to add a manual approval because allowance is laready exists", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualApproval( + account_investor1, + account_investor4, + web3.utils.toWei("2", "ether"), + latestTime() + duration.days(5), + { from: token_owner } + ) + ); + }); + it("Should fail to revoke manual approval because invalid _from address", async () => { await catchRevert(I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner })); }); @@ -452,6 +467,12 @@ contract("ManualApprovalTransferManager", accounts => { }); }); + it("Should fail to add a manual block because blocking already exist", async () => { + await catchRevert( + I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(5), { from: token_owner }) + ); + }); + it("Check manual block causes failure", async () => { await catchRevert(I_SecurityToken.transfer(account_investor2, web3.utils.toWei("1", "ether"), { from: account_investor1 })); }); @@ -507,21 +528,6 @@ contract("ManualApprovalTransferManager", accounts => { assert.equal(perm.length, 1); }); - // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { - // //Should fail initial transfer - // - // try { - // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - // } catch(error) { - // console.log(`Failed due to to count block`); - // ensureException(error); - // errorThrown = true; - // } - // //Add a manual approval - transfer should now work - // await I_ManualApprovalTransferManager.addManualApproval(account_investor2, account_investor5, web3.utils.toWei('1', 'ether'), latestTime() + duration.days(1), { from: token_owner }); - // await I_SecurityToken.transfer(account_investor5, web3.utils.toWei('1', 'ether'), { from: account_investor2 }); - // }); - it("Should get the init function", async () => { let byte = await I_ManualApprovalTransferManager.getInitFunction.call(); assert.equal(web3.utils.toAscii(byte).replace(/\u0000/g, ""), 0); @@ -544,6 +550,7 @@ contract("ManualApprovalTransferManager", accounts => { "Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.", "Wrong Module added" ); + assert.equal(await I_ManualApprovalTransferManagerFactory.getVersion.call(), "1.0.0"); }); it("Should get the tags of the factory", async () => { diff --git a/test/k_module_registry.js b/test/k_module_registry.js index 00da52285..193c53bad 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -8,10 +8,13 @@ import { setUpPolymathNetwork } from "./helpers/createInstances"; const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); +const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); +const ModuleRegistry = artifacts.require("./ModuleRegistry.sol"); const GeneralPermissionManagerFactory = artifacts.require("./GeneralPermissionManagerFactory.sol"); const GeneralTransferManagerFactory = artifacts.require("./GeneralTransferManagerFactory.sol"); const MockFactory = artifacts.require("./MockFactory.sol"); const TestSTOFactory = artifacts.require("./TestSTOFactory.sol"); +const ReclaimTokens = artifacts.require("./ReclaimTokens.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -47,9 +50,11 @@ contract("ModuleRegistry", accounts => { let I_SecurityTokenRegistry; let I_CappedSTOFactory1; let I_CappedSTOFactory2; + let I_CappedSTOFactory3; let I_STFactory; let I_MRProxied; let I_SecurityToken; + let I_ReclaimERC20; let I_STRProxied; let I_CappedSTO; let I_PolyToken; @@ -70,6 +75,7 @@ contract("ModuleRegistry", accounts => { const transferManagerKey = 2; const stoKey = 3; const budget = 0; + const address_zero = "0x0000000000000000000000000000000000000000"; // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); @@ -115,7 +121,7 @@ contract("ModuleRegistry", accounts => { I_STRProxied ] = instances; - I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); + I_ModuleRegistryProxy = await ModuleRegistryProxy.new({from: account_polymath}); // Printing all the contract addresses console.log(` @@ -133,6 +139,57 @@ contract("ModuleRegistry", accounts => { `); }); + describe("Test the initialize the function", async () => { + it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async () => { + let bytesProxy = encodeProxyCall(MRProxyParameters, [ + address_zero, + account_polymath + ]); + catchRevert( + I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, { + from: account_polymath + }), + "tx-> revert because polymathRegistry address is 0x" + ); + }); + + it("Should successfully update the implementation address -- fail because owner address is 0x", async () => { + let bytesProxy = encodeProxyCall(MRProxyParameters, [ + I_PolymathRegistry.address, + address_zero + ]); + catchRevert( + I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, { + from: account_polymath + }), + "tx-> revert because owner address is 0x" + ); + }); + + it("Should successfully update the implementation address -- fail because all params are 0x", async () => { + let bytesProxy = encodeProxyCall(MRProxyParameters, [ + address_zero, + address_zero + ]); + catchRevert( + I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, { + from: account_polymath + }), + "tx-> revert because all params are 0x" + ); + }); + + it("Should successfully update the implementation address", async() => { + let bytesProxy = encodeProxyCall(MRProxyParameters, [ + I_PolymathRegistry.address, + account_polymath + ]); + await I_ModuleRegistryProxy.upgradeToAndCall("1.0.0", I_ModuleRegistry.address, bytesProxy, { from: account_polymath }); + I_MRProxied = await ModuleRegistry.at(I_ModuleRegistryProxy.address); + await I_PolymathRegistry.changeAddress("ModuleRegistry", I_ModuleRegistryProxy.address, { from: account_polymath }); + }) + }); + describe("Test cases for the ModuleRegistry", async () => { describe("Test case for the upgradeFromregistry", async () => { it("Should successfully update the registry contract address -- failed because of bad owner", async () => { @@ -191,8 +248,8 @@ contract("ModuleRegistry", accounts => { assert.equal(tx.logs[0].args._owner, account_polymath, "Should be the right owner"); let _list = await I_MRProxied.getModulesByType(transferManagerKey); - assert.equal(_list.length, 2, "Length should be 2"); - assert.equal(_list[1], I_GeneralTransferManagerFactory.address); + assert.equal(_list.length, 1, "Length should be 1"); + assert.equal(_list[0], I_GeneralTransferManagerFactory.address); let _reputation = await I_MRProxied.getReputationByFactory(I_GeneralTransferManagerFactory.address); assert.equal(_reputation.length, 0); @@ -205,8 +262,22 @@ contract("ModuleRegistry", accounts => { it("Should fail in registering the module-- type = 0", async () => { I_MockFactory = await MockFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath }); - await catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); + catchRevert(I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath })); + }); + + it("Should fail to register the new module because msg.sender is not the owner of the module", async() => { + I_CappedSTOFactory3 = await CappedSTOFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_temp }); + catchRevert( + I_MRProxied.registerModule(I_CappedSTOFactory3.address, { from: token_owner }) + ); }); + + it("Should successfully register the module -- fail because no module type uniqueness", async() => { + await I_MockFactory.changeTypes({from: account_polymath }); + catchRevert( + I_MRProxied.registerModule(I_MockFactory.address, { from: account_polymath }) + ); + }) }); describe("Test case for verifyModule", async () => { @@ -256,7 +327,7 @@ contract("ModuleRegistry", accounts => { assert.notEqual( I_CappedSTOFactory2.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "CappedSTOFactory contract was not deployed" ); @@ -294,6 +365,16 @@ contract("ModuleRegistry", accounts => { assert.equal(_reputation.length, 1); }); + it("Should successfully add module when custom modules switched on -- fail because factory owner is different", async() => { + await I_MRProxied.registerModule(I_CappedSTOFactory3.address, { from: account_temp }) + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + catchRevert( + I_SecurityToken.addModule(I_CappedSTOFactory3.address, bytesSTO, 0, 0, { from: token_owner }) + ); + }) + it("Should successfully add verified module", async () => { I_GeneralPermissionManagerFactory = await GeneralPermissionManagerFactory.new(I_PolyToken.address, 0, 0, 0, { from: account_polymath @@ -398,25 +479,27 @@ contract("ModuleRegistry", accounts => { let sto1 = (await I_MRProxied.getModulesByType.call(3))[0]; let sto2 = (await I_MRProxied.getModulesByType.call(3))[1]; + let sto3 = (await I_MRProxied.getModulesByType.call(3))[2]; + let sto4 = (await I_MRProxied.getModulesByType.call(3))[3]; assert.equal(sto1, I_CappedSTOFactory1.address); assert.equal(sto2, I_CappedSTOFactory2.address); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 4); - let tx = await I_MRProxied.removeModule(sto1, { from: account_polymath }); + let tx = await I_MRProxied.removeModule(sto4, { from: account_polymath }); - assert.equal(tx.logs[0].args._moduleFactory, sto1, "Event is not properly emitted for _moduleFactory"); + assert.equal(tx.logs[0].args._moduleFactory, sto4, "Event is not properly emitted for _moduleFactory"); assert.equal(tx.logs[0].args._decisionMaker, account_polymath, "Event is not properly emitted for _decisionMaker"); - let sto2_end = (await I_MRProxied.getModulesByType.call(3))[1]; + let sto3_end = (await I_MRProxied.getModulesByType.call(3))[2]; // re-ordering - assert.equal(sto2_end, sto2); + assert.equal(sto3_end, sto3); // delete related data - assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto1)), 0); - assert.equal(await I_MRProxied.getReputationByFactory.call(sto1), 0); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); - assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto1)), false); + assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto4)), 0); + assert.equal(await I_MRProxied.getReputationByFactory.call(sto4), 0); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); + assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto4)), false); await revertToSnapshot(snap); }); @@ -427,7 +510,7 @@ contract("ModuleRegistry", accounts => { assert.equal(sto1, I_CappedSTOFactory1.address); assert.equal(sto2, I_CappedSTOFactory2.address); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 4); let tx = await I_MRProxied.removeModule(sto2, { from: token_owner }); @@ -441,7 +524,7 @@ contract("ModuleRegistry", accounts => { // delete related data assert.equal(await I_MRProxied.getUintValues.call(web3.utils.soliditySha3("registry", sto2)), 0); assert.equal(await I_MRProxied.getReputationByFactory.call(sto2), 0); - assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 2); + assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); assert.equal(await I_MRProxied.getBoolValues.call(web3.utils.soliditySha3("verified", sto2)), false); }); @@ -452,6 +535,20 @@ contract("ModuleRegistry", accounts => { describe("Test cases for IRegistry functionality", async () => { describe("Test cases for reclaiming funds", async () => { + + it("Should successfully reclaim POLY tokens -- fail because token address will be 0x", async() => { + await I_PolyToken.transfer(I_MRProxied.address, web3.utils.toWei("1"), { from: token_owner }); + catchRevert( + I_MRProxied.reclaimERC20("0x000000000000000000000000000000000000000", { from: account_polymath }) + ); + }); + + it("Should successfully reclaim POLY tokens -- not authorised", async() => { + catchRevert( + I_MRProxied.reclaimERC20(I_PolyToken.address, { from: account_temp }) + ); + }); + it("Should successfully reclaim POLY tokens", async () => { await I_PolyToken.getTokens(web3.utils.toWei("1"), I_MRProxied.address); let bal1 = await I_PolyToken.balanceOf.call(account_polymath); @@ -485,6 +582,48 @@ contract("ModuleRegistry", accounts => { assert.isNotOk(status); }); }); + + describe("Test cases for the ReclaimTokens contract", async() => { + + it("Should successfully reclaim POLY tokens -- fail because token address will be 0x", async() => { + I_ReclaimERC20 = await ReclaimTokens.at(I_FeatureRegistry.address); + await I_PolyToken.transfer(I_ReclaimERC20.address, web3.utils.toWei("1"), { from: token_owner }); + catchRevert( + I_ReclaimERC20.reclaimERC20("0x000000000000000000000000000000000000000", { from: account_polymath }) + ); + }); + + it("Should successfully reclaim POLY tokens -- not authorised", async() => { + catchRevert( + I_ReclaimERC20.reclaimERC20(I_PolyToken.address, { from: account_temp }) + ); + }); + + it("Should successfully reclaim POLY tokens", async () => { + await I_PolyToken.getTokens(web3.utils.toWei("1"), I_ReclaimERC20.address); + let bal1 = await I_PolyToken.balanceOf.call(account_polymath); + await I_ReclaimERC20.reclaimERC20(I_PolyToken.address); + let bal2 = await I_PolyToken.balanceOf.call(account_polymath); + assert.isAtLeast( + bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), + bal2.dividedBy(new BigNumber(10).pow(18)).toNumber() + ); + }); + }) + + describe("Test case for the PolymathRegistry", async() => { + + it("Should successfully get the address -- fail because key is not exist", async() => { + catchRevert( + I_PolymathRegistry.getAddress("PolyOracle") + ); + }); + + it("Should successfully get the address", async() => { + let _moduleR = await I_PolymathRegistry.getAddress("ModuleRegistry"); + assert.equal(_moduleR, I_ModuleRegistryProxy.address); + }) + }) }); }); }); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index c9e03ecfb..3a62463ac 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -320,6 +320,10 @@ contract("PercentageTransferManager", accounts => { let snapId = await takeSnapshot(); await I_PercentageTransferManager.setAllowPrimaryIssuance(true, { from: token_owner }); await I_SecurityToken.mint(account_investor3, web3.utils.toWei('100', 'ether'), { from: token_owner }); + // trying to call it again with the same value. should fail + await catchRevert( + I_PercentageTransferManager.setAllowPrimaryIssuance(true, { from: token_owner }) + ) await revertToSnapshot(snapId); }); @@ -342,6 +346,18 @@ contract("PercentageTransferManager", accounts => { await I_SecurityToken.transfer(account_investor3, web3.utils.toWei("2", "ether"), { from: account_investor1 }); }); + it("Should whitelist in batch --failed because of mismatch in array lengths", async() => { + await catchRevert( + I_PercentageTransferManager.modifyWhitelistMulti([account_investor3, account_investor4], [false], { from: token_owner }) + ); + }) + + it("Should whitelist in batch", async() => { + let snapId = await takeSnapshot(); + await I_PercentageTransferManager.modifyWhitelistMulti([account_investor3, account_investor4], [false, true], { from: token_owner }); + await revertToSnapshot(snapId); + }) + it("Should be able to whitelist address and then transfer regardless of holders", async () => { await I_PercentageTransferManager.changeHolderPercentage(30 * 10 ** 16, { from: token_owner }); await I_PercentageTransferManager.modifyWhitelist(account_investor1, true, { from: token_owner }); @@ -374,6 +390,7 @@ contract("PercentageTransferManager", accounts => { "Allows an issuer to restrict the total number of non-zero token holders", "Wrong Module added" ); + assert.equal(await I_PercentageTransferManagerFactory.getVersion.call(), "1.0.0"); }); it("Should get the tags of the factory", async () => { diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index df605d86e..4e2e80327 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -41,6 +41,7 @@ contract("PreSaleSTO", accounts => { let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_PreSaleSTOFactory; + let P_PreSaleSTOFactory; let I_STFactory; let I_SecurityToken; let I_MRProxied; @@ -69,6 +70,7 @@ contract("PreSaleSTO", accounts => { // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); let endTime; + const address_zero = "0x0000000000000000000000000000000000000000"; const STOParameters = ["uint256"]; before(async () => { @@ -99,6 +101,8 @@ contract("PreSaleSTO", accounts => { // STEP 4: Deploy the PreSaleSTOFactory [I_PreSaleSTOFactory] = await deployPresaleSTOAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); + // STEP 5: Deploy the paid PresaleSTOFactory + [P_PreSaleSTOFactory] = await deployPresaleSTOAndVerified(account_polymath, I_MRProxied, I_PolyToken.address, 0); // Printing all the contract addresses console.log(` @@ -154,6 +158,46 @@ contract("PreSaleSTO", accounts => { await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner })); }); + it("Should successfully attach the Paid STO factory with the security token", async () => { + let snap_id = await takeSnapshot(); + endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time + let bytesSTO = encodeModuleCall(STOParameters, [endTime]); + await I_PolyToken.getTokens(web3.utils.toWei("500"), I_SecurityToken.address); + const tx = await I_SecurityToken.addModule(P_PreSaleSTOFactory.address, bytesSTO, web3.utils.toWei("500"), 0, { from: token_owner }); + + assert.equal(tx.logs[2].args._types[0], stoKey, "PreSaleSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), + "PreSaleSTO", + "PreSaleSTOFactory module was not added" + ); + I_PreSaleSTO = PreSaleSTO.at(tx.logs[2].args._module); + await revertToSnapshot(snap_id); + }); + + it("Should successfully attach the STO factory with the security token -- fail because signature is different", async () => { + endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time + let bytesSTO = encodeModuleCall(["string"], ["hey"]); + await catchRevert( + I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }) + ); + }); + + it("Should successfully attach the STO factory with the security token", async () => { + endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time + let bytesSTO = encodeModuleCall(STOParameters, [endTime]); + + const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, 0, 0, { from: token_owner }); + + assert.equal(tx.logs[2].args._types[0], stoKey, "PreSaleSTO doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), + "PreSaleSTO", + "PreSaleSTOFactory module was not added" + ); + I_PreSaleSTO = PreSaleSTO.at(tx.logs[2].args._module); + }); + it("Should successfully attach the STO factory with the security token", async () => { endTime = latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time let bytesSTO = encodeModuleCall(STOParameters, [endTime]); @@ -211,6 +255,14 @@ contract("PreSaleSTO", accounts => { // assert.isTrue(false); }); + it("Should allocate the tokens --failed because of amount is 0", async() => { + await catchRevert( + I_PreSaleSTO.allocateTokens(account_investor1, 0, web3.utils.toWei("1", "ether"), 0, { + from: account_issuer + }) + ); + }) + it("Should allocate the tokens -- failed due to msg.sender is not pre sale admin", async () => { await catchRevert( I_PreSaleSTO.allocateTokens(account_investor1, web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether"), 0, { @@ -252,6 +304,54 @@ contract("PreSaleSTO", accounts => { assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 3); }); + it("Should successfully mint multiple tokens -- failed because array mismatch", async() => { + await catchRevert( + I_PreSaleSTO.allocateTokensMulti( + [account_investor2], + [web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether")], + [0, 0], + [web3.utils.toWei("1000", "ether"), web3.utils.toWei("1000", "ether")], + { from: account_issuer } + ) + ); + }) + + it("Should successfully mint multiple tokens -- failed because array mismatch", async() => { + await catchRevert( + I_PreSaleSTO.allocateTokensMulti( + [account_investor2, account_investor3], + [web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether")], + [0], + [web3.utils.toWei("1000", "ether"), web3.utils.toWei("1000", "ether")], + { from: account_issuer } + ) + ); + }); + + it("Should successfully mint multiple tokens -- failed because array mismatch", async() => { + await catchRevert( + I_PreSaleSTO.allocateTokensMulti( + [account_investor2, account_investor3], + [web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether")], + [0,0], + [web3.utils.toWei("1000", "ether")], + { from: account_issuer } + ) + ); + }); + + it("Should successfully mint multiple tokens -- failed because array mismatch", async() => { + await catchRevert( + I_PreSaleSTO.allocateTokensMulti( + [account_investor2, account_investor3], + [web3.utils.toWei("1", "ether"), web3.utils.toWei("1", "ether")], + [0], + [web3.utils.toWei("1000", "ether"), web3.utils.toWei("1000", "ether")], + { from: account_issuer } + ) + ); + }); + it("Should failed at the time of buying the tokens -- Because STO has started", async () => { await increaseTime(duration.days(100)); // increased beyond the end time of the STO @@ -267,7 +367,7 @@ contract("PreSaleSTO", accounts => { await I_PolyToken.getTokens(value, account_investor1); await I_PolyToken.transfer(I_PreSaleSTO.address, value, { from: account_investor1 }); - await catchRevert(I_PreSaleSTO.reclaimERC20("0x0000000000000000000000000000000000000000", { from: token_owner })); + await catchRevert(I_PreSaleSTO.reclaimERC20(address_zero, { from: token_owner })); }); it("Should successfully reclaim POLY", async () => { @@ -298,6 +398,11 @@ contract("PreSaleSTO", accounts => { "tokens are not trandfered out from STO contract" ); }); + + it("Should get the the tokens sold", async() => { + let _tokensSold = await I_PreSaleSTO.getTokensSold.call(); + console.log(_tokensSold); + }) }); describe("Test cases for the PresaleSTOFactory", async () => { diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index dc5fc80d5..9000b87ed 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -70,6 +70,7 @@ contract("SecurityTokenRegistry", accounts => { const name2 = "Demo2 Token"; const symbol2 = "DET2"; const tokenDetails2 = "This is equity type of issuance"; + const address_zero = "0x0000000000000000000000000000000000000000"; // Module key const permissionManagerKey = 1; @@ -125,7 +126,7 @@ contract("SecurityTokenRegistry", accounts => { assert.notEqual( I_SecurityTokenRegistry.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "SecurityTokenRegistry contract was not deployed" ); @@ -155,7 +156,7 @@ contract("SecurityTokenRegistry", accounts => { describe("Test the initialize the function", async () => { it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async () => { let bytesProxy = encodeProxyCall(STRProxyParameters, [ - "0x0000000000000000000000000000000000000000", + address_zero, I_STFactory.address, initRegFee, initRegFee, @@ -173,7 +174,7 @@ contract("SecurityTokenRegistry", accounts => { it("Should successfully update the implementation address -- fail because STFactory address is 0x", async () => { let bytesProxy = encodeProxyCall(STRProxyParameters, [ I_PolymathRegistry.address, - "0x0000000000000000000000000000000000000000", + address_zero, initRegFee, initRegFee, I_PolyToken.address, @@ -227,7 +228,7 @@ contract("SecurityTokenRegistry", accounts => { I_STFactory.address, initRegFee, initRegFee, - "0x0000000000000000000000000000000000000000", + address_zero, account_polymath ]); catchRevert( @@ -245,7 +246,24 @@ contract("SecurityTokenRegistry", accounts => { initRegFee, initRegFee, I_PolyToken.address, - "0x0000000000000000000000000000000000000000" + address_zero + ]); + catchRevert( + I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { + from: account_polymath + }), + "tx-> revert because owner address is 0x" + ); + }); + + it("Should successfully update the implementation address -- fail because all params get 0", async () => { + let bytesProxy = encodeProxyCall(STRProxyParameters, [ + address_zero, + address_zero, + 0, + 0, + address_zero, + address_zero ]); catchRevert( I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { @@ -321,7 +339,7 @@ contract("SecurityTokenRegistry", accounts => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_temp }); catchRevert( - I_STRProxied.registerTicker("0x0000000000000000000000000000000000000000", symbol, name, { from: account_temp }), + I_STRProxied.registerTicker(address_zero, symbol, name, { from: account_temp }), "tx revert -> owner should not be 0x" ); }); @@ -343,6 +361,15 @@ contract("SecurityTokenRegistry", accounts => { assert.equal(tx.logs[0].args._ticker, symbol, `Symbol should be ${symbol}`); }); + it("Should register the ticker when the tickerRegFee is 0", async() => { + let snap_Id = await takeSnapshot(); + await I_STRProxied.changeTickerRegistrationFee(0, { from: account_polymath }); + let tx = await I_STRProxied.registerTicker(account_temp, "ZERO", name, { from: account_temp }); + assert.equal(tx.logs[0].args._owner, account_temp, `Owner should be the ${account_temp}`); + assert.equal(tx.logs[0].args._ticker, "ZERO", `Symbol should be ZERO`); + await revertToSnapshot(snap_Id); + }) + it("Should fail to register same symbol again", async () => { // Give POLY to token issuer await I_PolyToken.getTokens(initRegFee, token_owner); @@ -421,7 +448,7 @@ contract("SecurityTokenRegistry", accounts => { it("Should get the details of unregistered token", async () => { let tx = await I_STRProxied.getTickerDetails.call("TORO"); - assert.equal(tx[0], "0x0000000000000000000000000000000000000000", "Should be 0x as ticker is not exists in the registry"); + assert.equal(tx[0], address_zero, "Should be 0x as ticker is not exists in the registry"); assert.equal(tx[3], "", "Should be an empty string"); assert.equal(tx[4], false, "Status if the symbol should be undeployed -- false"); }); @@ -435,7 +462,7 @@ contract("SecurityTokenRegistry", accounts => { assert.equal(data[4], false, "Token is not launched yet so it should return False"); data = await I_SecurityTokenRegistry.getTickerDetails(symbol, { from: token_owner }); console.log("This is the data from the original securityTokenRegistry contract"); - assert.equal(data[0], "0x0000000000000000000000000000000000000000", "Token owner should be 0x"); + assert.equal(data[0], address_zero, "Token owner should be 0x"); }); it("Should fail to generate new security token if fee not provided", async () => { @@ -475,7 +502,7 @@ contract("SecurityTokenRegistry", accounts => { it("Should fail to generate the securityToken -- Because msg.sender is not the rightful owner of the ticker", async () => { catchRevert( - I_STRProxied.generateSecurityToken("", symbol, tokenDetails, false, { from: account_temp }), + I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, { from: account_temp }), "tx revert -> Because msg.sender is not the rightful owner of the ticker" ); }); @@ -502,6 +529,27 @@ contract("SecurityTokenRegistry", accounts => { "tx revert -> Because ticker is already in use" ); }); + + it("Should fail to generate the SecurityToken because ticker gets expired", async() => { + let snap_Id = await takeSnapshot(); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, "CCC", name, { from: token_owner }); + await increaseTime(duration.days(65)); + catchRevert( + I_STRProxied.generateSecurityToken(name, "CCC", tokenDetails, false, { from: token_owner }), + "tx revert -> Because ticker is expired" + ); + await revertToSnapshot(snap_Id); + }); + + it("Should generate the SecurityToken when launch fee is 0", async() => { + let snap_Id = await takeSnapshot(); + await I_STRProxied.changeSecurityLaunchFee(0, { from: account_polymath }); + await I_PolyToken.approve(I_STRProxied.address, web3.utils.toWei("500"), { from: token_owner }); + let tx = await I_STRProxied.registerTicker(token_owner, "CCC", name, { from: token_owner }); + await I_STRProxied.generateSecurityToken(name, "CCC", tokenDetails, false, { from: token_owner }), + await revertToSnapshot(snap_Id); + }); }); describe("Generate SecurityToken v2", async () => { @@ -512,7 +560,7 @@ contract("SecurityTokenRegistry", accounts => { assert.notEqual( I_STFactory002.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "STFactory002 contract was not deployed" ); await I_STRProxied.setProtocolVersion(I_STFactory002.address, 0, 2, 0, { from: account_polymath }); @@ -554,7 +602,7 @@ contract("SecurityTokenRegistry", accounts => { I_SecurityTokenRegistryV2 = await SecurityTokenRegistryMock.new({ from: account_polymath }); assert.notEqual( I_SecurityTokenRegistryV2.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "SecurityTokenRegistry contract was not deployed" ); }); @@ -597,6 +645,15 @@ contract("SecurityTokenRegistry", accounts => { ); }); + it("Should fail to genrate the custom security token -- ticker length is greater than 10 chars", async() => { + catchRevert( + I_STRProxied.modifySecurityToken("LOGAN", "LOGLOGLOGLOG", account_temp, dummy_token, "I am custom ST", latestTime(), { + from: account_polymath + }), + "tx revert -> msg.sender is not polymath account" + ); + }) + it("Should fail to generate the custom security token -- name should not be 0 length ", async () => { catchRevert( I_STRProxied.modifySecurityToken("", "LOG", account_temp, dummy_token, "I am custom ST", latestTime(), { @@ -678,6 +735,12 @@ contract("SecurityTokenRegistry", accounts => { assert.equal(symbolDetails[0], account_temp, `Owner of the symbol should be ${account_temp}`); assert.equal(symbolDetails[3], "LOGAN2", `Name of the symbol should be LOGAN`); }); + + it("Should successfully modify the ticker", async() => { + let snap_Id = await takeSnapshot(); + let tx = await I_STRProxied.modifyTicker(account_temp, "LOG2", "LOGAN2", latestTime(), latestTime() + duration.days(60), false, {from: account_polymath}); + await revertToSnapshot(snap_Id); + }) }); describe("Test case for modifyTicker", async () => { @@ -1026,10 +1089,23 @@ contract("SecurityTokenRegistry", accounts => { }); describe("Test cases for IRegistry functionality", async () => { describe("Test cases for reclaiming funds", async () => { - it("Should successfully reclaim POLY tokens", async () => { + + it("Should successfully reclaim POLY tokens -- fail because token address will be 0x", async() => { I_PolyToken.transfer(I_STRProxied.address, web3.utils.toWei("1"), { from: token_owner }); + catchRevert( + I_STRProxied.reclaimERC20("0x000000000000000000000000000000000000000", { from: account_polymath }) + ); + }); + + it("Should successfully reclaim POLY tokens -- not authorised", async() => { + catchRevert( + I_STRProxied.reclaimERC20(I_PolyToken.address, { from: account_temp }) + ); + }); + + it("Should successfully reclaim POLY tokens", async () => { let bal1 = await I_PolyToken.balanceOf.call(account_polymath); - await I_STRProxied.reclaimERC20(I_PolyToken.address); + await I_STRProxied.reclaimERC20(I_PolyToken.address, { from: account_polymath }); let bal2 = await I_PolyToken.balanceOf.call(account_polymath); assert.isAtLeast( bal2.dividedBy(new BigNumber(10).pow(18)).toNumber(), @@ -1059,5 +1135,57 @@ contract("SecurityTokenRegistry", accounts => { assert.isNotOk(status); }); }); + + describe("Test cases for the setProtocolVersion", async() => { + + it("Should successfully change the protocolVersion -- failed because of bad owner", async() => { + catchRevert( + I_STRProxied.setProtocolVersion(accounts[8], 5, 6, 7, { from: account_temp }) + ); + }); + + it("Should successfully change the protocolVersion -- failed because factory address is 0x", async() => { + catchRevert( + I_STRProxied.setProtocolVersion("0x000000000000000000000000000000000000000", 5, 6, 7, { from: account_polymath }) + ); + }); + + it("Should successfully change the protocolVersion -- not a valid vesrion", async() => { + catchRevert( + I_STRProxied.setProtocolVersion(accounts[8], 0, 0, 0, { from: account_polymath }) + ); + }); + + it("Should successfully change the protocolVersion -- fail in second attempt because of invalid version", async() => { + let snap_Id = await takeSnapshot(); + await I_STRProxied.setProtocolVersion(accounts[8], 1, 2, 1, {from: account_polymath }); + await catchRevert( + I_STRProxied.setProtocolVersion(accounts[8], 0, 2, 1, {from: account_polymath }) + ); + await revertToSnapshot(snap_Id); + }); + + }); + + describe("Test cases for the transferOwnership", async() => { + + it("Should fail to transfer the ownership -- not authorised", async() => { + catchRevert( + I_STRProxied.transferOwnership(account_temp, { from: account_issuer}) + ); + }); + + it("Should fail to transfer the ownership -- 0x address is not allowed", async() => { + catchRevert( + I_STRProxied.transferOwnership("0x000000000000000000000000000000000000000", { from: account_polymath}) + ); + }); + + it("Should successfully transfer the ownership of the STR", async() => { + let tx = await I_STRProxied.transferOwnership(account_temp, { from: account_polymath }); + assert.equal(tx.logs[0].args.previousOwner, account_polymath); + assert.equal(tx.logs[0].args.newOwner, account_temp); + }); + }) }); }); diff --git a/test/o_security_token.js b/test/o_security_token.js index b5ca2dbdf..619b80035 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -3,13 +3,20 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall, encodeModuleCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork, deployGPMAndVerifyed, deployCappedSTOAndVerifyed } from "./helpers/createInstances"; +import { + setUpPolymathNetwork, + deployGPMAndVerifyed, + deployCappedSTOAndVerifyed, + deployMockRedemptionAndVerifyed, + deployMockWrongTypeRedemptionAndVerifyed + } from "./helpers/createInstances"; const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const GeneralPermissionManager = artifacts.require("./GeneralPermissionManager"); +const MockRedemptionManager = artifacts.require("./MockRedemptionManager.sol"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -58,6 +65,9 @@ contract("SecurityToken", accounts => { let I_CappedSTO; let I_PolyToken; let I_PolymathRegistry; + let I_MockRedemptionManagerFactory; + let I_MockRedemptionManager; + // SecurityToken Details (Launched ST on the behalf of the issuer) const name = "Demo Token"; @@ -69,6 +79,7 @@ contract("SecurityToken", accounts => { const permissionManagerKey = 1; const transferManagerKey = 2; const stoKey = 3; + const burnKey = 5; const budget = 0; // Initial fee for ticker registry and security token registry @@ -377,6 +388,43 @@ contract("SecurityToken", accounts => { let tx = await I_SecurityToken.removeModule(I_GeneralTransferManager.address, { from: token_owner }); assert.equal(tx.logs[0].args._types[0], transferManagerKey); assert.equal(tx.logs[0].args._module, I_GeneralTransferManager.address); + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("500"), {from: token_owner}); + await I_SecurityToken.transfer(account_investor2, web3.utils.toWei("200"), {from: account_investor1 }); + assert.equal((await I_SecurityToken.balanceOf(account_investor2)).dividedBy(new BigNumber(10).pow(18)).toNumber(), 200); + await revertToSnapshot(key); + }); + + it("Should successfully remove the module from the middle of the names mapping", async() => { + let snap_Id = await takeSnapshot(); + let D_GPM, D_GPM_1, D_GPM_2; + let FactoryInstances; + let GPMAddress = new Array(); + + [D_GPM] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [D_GPM_1] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [D_GPM_2] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + FactoryInstances = [D_GPM, D_GPM_1, D_GPM_2]; + // Adding module in the ST + for (let i = 0; i < FactoryInstances.length; i++) { + let tx = await I_SecurityToken.addModule(FactoryInstances[i].address, "", 0, 0, {from: token_owner }); + assert.equal(tx.logs[2].args._types[0], permissionManagerKey, "fail in adding the GPM") + GPMAddress.push(tx.logs[2].args._module); + } + // Archive the one of the module + await I_SecurityToken.archiveModule(GPMAddress[0], {from: token_owner}); + // Remove the module + let tx = await I_SecurityToken.removeModule(GPMAddress[0], {from: token_owner}); + assert.equal(tx.logs[0].args._types[0], permissionManagerKey); + assert.equal(tx.logs[0].args._module, GPMAddress[0]); + await revertToSnapshot(snap_Id); + }); + + it("Should successfully archive the module first and fail during achiving the module again", async() => { + let key = await takeSnapshot(); + await I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }); + await catchRevert( + I_SecurityToken.archiveModule(I_GeneralTransferManager.address, { from: token_owner }) + ); await revertToSnapshot(key); }); @@ -416,6 +464,18 @@ contract("SecurityToken", accounts => { assert.equal(moduleData[3], false); }); + it("Should successfully unarchive the general transfer manager module from the securityToken -- fail because module is already unarchived", async () => { + await catchRevert( + I_SecurityToken.unarchiveModule(I_GeneralTransferManager.address, { from: token_owner }) + ); + }); + + it("Should successfully archive the module -- fail because module is not existed", async() => { + await catchRevert( + I_SecurityToken.archiveModule(I_GeneralPermissionManagerFactory.address, { from: token_owner }) + ); + }) + it("Should fail to mint tokens while GTM unarchived", async () => { await catchRevert(I_SecurityToken.mint(1, 100 * Math.pow(10, 18), { from: token_owner, gas: 500000 })); }); @@ -430,6 +490,19 @@ contract("SecurityToken", accounts => { assert.equal(tx.logs[1].args._module, I_CappedSTO.address); assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 100); }); + + it("Should change the budget of the module (decrease it)", async() => { + let tx = await I_SecurityToken.changeModuleBudget(I_CappedSTO.address, 50 * Math.pow(10, 18), { from: token_owner }); + assert.equal(tx.logs[1].args._moduleTypes[0], stoKey); + assert.equal(tx.logs[1].args._module, I_CappedSTO.address); + assert.equal(tx.logs[1].args._budget.dividedBy(new BigNumber(10).pow(18)).toNumber(), 50); + }); + + it("Should fail to get the total supply -- because checkpoint id is greater than present", async() => { + await catchRevert( + I_SecurityToken.totalSupplyAt.call(50) + ); + }) }); describe("General Transfer manager Related test cases", async () => { @@ -803,14 +876,94 @@ contract("SecurityToken", accounts => { }); }); + describe("Test cases for the Mock TrackedRedeemption", async() => { + + it("Should add the tracked redeemption module successfully", async() => { + [I_MockRedemptionManagerFactory] = await deployMockRedemptionAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + let tx = await I_SecurityToken.addModule(I_MockRedemptionManagerFactory.address, "", 0, 0, {from: token_owner }); + assert.equal(tx.logs[2].args._types[0], burnKey, "fail in adding the burn manager"); + I_MockRedemptionManager = MockRedemptionManager.at(tx.logs[2].args._module); + // adding the burn module into the GTM + tx = await I_GeneralTransferManager.modifyWhitelist( + I_MockRedemptionManager.address, + latestTime(), + latestTime() + duration.seconds(2), + latestTime() + duration.days(50), + true, + { + from: account_delegate, + gas: 6000000 + } + ); + assert.equal(tx.logs[0].args._investor, I_MockRedemptionManager.address, "Failed in adding the investor in whitelist"); + }); + + it("Should successfully burn tokens", async() => { + await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(false, {from: token_owner}); + // Minting some tokens + await I_SecurityToken.mint(account_investor1, web3.utils.toWei("1000"), {from: token_owner}); + // Provide approval to trnafer the tokens to Module + await I_SecurityToken.approve(I_MockRedemptionManager.address, web3.utils.toWei("500"), {from: account_investor1}); + // Allow all whitelist transfer + await I_GeneralTransferManager.changeAllowAllWhitelistTransfers(true, {from: token_owner}); + // Transfer the tokens to module (Burn) + await I_MockRedemptionManager.transferToRedeem(web3.utils.toWei("500"), { from: account_investor1}); + // Redeem tokens + let tx = await I_MockRedemptionManager.redeemTokenByOwner(web3.utils.toWei("250"), {from: account_investor1}); + assert.equal(tx.logs[0].args._investor, account_investor1, "Burn tokens of wrong owner"); + assert.equal((tx.logs[0].args._value).dividedBy(new BigNumber(10).pow(18)).toNumber(), 250); + }); + + it("Should fail to burn the tokens because module get archived", async() => { + await I_SecurityToken.archiveModule(I_MockRedemptionManager.address, {from: token_owner}); + await catchRevert( + I_MockRedemptionManager.redeemTokenByOwner(web3.utils.toWei("250"), {from: account_investor1}) + ); + }) + + it("Should successfully fail in calling the burn functions", async() => { + [I_MockRedemptionManagerFactory] = await deployMockWrongTypeRedemptionAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + let tx = await I_SecurityToken.addModule(I_MockRedemptionManagerFactory.address, "", 0, 0, {from: token_owner }); + I_MockRedemptionManager = MockRedemptionManager.at(tx.logs[2].args._module); + + // adding the burn module into the GTM + tx = await I_GeneralTransferManager.modifyWhitelist( + I_MockRedemptionManager.address, + latestTime(), + latestTime() + duration.seconds(2), + latestTime() + duration.days(50), + true, + { + from: account_delegate, + gas: 6000000 + } + ); + assert.equal(tx.logs[0].args._investor, I_MockRedemptionManager.address, "Failed in adding the investor in whitelist"); + // Provide approval to trnafer the tokens to Module + await I_SecurityToken.approve(I_MockRedemptionManager.address, web3.utils.toWei("500"), {from: account_investor1}); + // Transfer the tokens to module (Burn) + await I_MockRedemptionManager.transferToRedeem(web3.utils.toWei("500"), { from: account_investor1}); + + await catchRevert( + // Redeem tokens + I_MockRedemptionManager.redeemTokenByOwner(web3.utils.toWei("250"), {from: account_investor1}) + ); + }); + + }) + describe("Withdraw Poly", async () => { + it("Should successfully withdraw the poly -- failed because of zero address of token", async() => { + await catchRevert(I_SecurityToken.withdrawERC20("0x00000000000000000000000000000000000000000", web3.utils.toWei("20000", "ether"), { from: account_temp })); + }) + it("Should successfully withdraw the poly", async () => { - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), { from: account_temp })); + await catchRevert(I_SecurityToken.withdrawERC20(I_PolyToken.address, web3.utils.toWei("20000", "ether"), { from: account_temp })); }); it("Should successfully withdraw the poly", async () => { let balanceBefore = await I_PolyToken.balanceOf(token_owner); - await I_SecurityToken.withdrawPoly(web3.utils.toWei("20000", "ether"), { from: token_owner }); + await I_SecurityToken.withdrawERC20(I_PolyToken.address, web3.utils.toWei("20000", "ether"), { from: token_owner }); let balanceAfter = await I_PolyToken.balanceOf(token_owner); assert.equal( BigNumber(balanceAfter) @@ -821,7 +974,7 @@ contract("SecurityToken", accounts => { }); it("Should successfully withdraw the poly", async () => { - await catchRevert(I_SecurityToken.withdrawPoly(web3.utils.toWei("10", "ether"), { from: token_owner })); + await catchRevert(I_SecurityToken.withdrawERC20(I_PolyToken.address, web3.utils.toWei("10", "ether"), { from: token_owner })); }); }); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 73856e2cf..62cd4cc05 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -58,6 +58,7 @@ contract("USDTieredSTO", accounts => { let I_PolyToken; let I_DaiToken; let I_PolymathRegistry; + let P_USDTieredSTOFactory; // SecurityToken Details for funds raise Type ETH const NAME = "Team"; @@ -68,6 +69,8 @@ contract("USDTieredSTO", accounts => { // Module key const TMKEY = 2; const STOKEY = 3; + let snapId; + const address_zero = "0x0000000000000000000000000000000000000000"; // Initial fee for ticker registry and security token registry const REGFEE = web3.utils.toWei("250"); @@ -226,7 +229,7 @@ contract("USDTieredSTO", accounts => { // STEP 5: Deploy the USDTieredSTOFactory [I_USDTieredSTOFactory] = await deployUSDTieredSTOAndVerified(POLYMATH, I_MRProxied, I_PolyToken.address, STOSetupCost); - + [P_USDTieredSTOFactory] = await deployUSDTieredSTOAndVerified(POLYMATH, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); // 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 @@ -371,6 +374,83 @@ contract("USDTieredSTO", accounts => { assert.equal((await I_USDTieredSTO_Array[stoId].getPermissions()).length, 0, "Incorrect number of permissions"); }); + it("Should attach the paid STO factory -- failed because of no tokens", async() => { + let stoId = 0; // No discount + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + await catchRevert( + I_SecurityToken.addModule(P_USDTieredSTOFactory.address, bytesSTO, web3.utils.toWei("500"), 0, { from: ISSUER, gasPrice: GAS_PRICE }) + ); + }); + + it("Should attach the paid STO factory", async() => { + let snapId = await takeSnapshot(); + let stoId = 0; // No discount + let config = [ + _startTime[stoId], + _endTime[stoId], + _ratePerTier[stoId], + _ratePerTierDiscountPoly[stoId], + _tokensPerTierTotal[stoId], + _tokensPerTierDiscountPoly[stoId], + _nonAccreditedLimitUSD[stoId], + _minimumInvestmentUSD[stoId], + _fundRaiseTypes[stoId], + _wallet[stoId], + _reserveWallet[stoId], + _usdToken[stoId] + ]; + + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); + await I_PolyToken.getTokens(web3.utils.toWei("500"), I_SecurityToken.address); + let tx = await I_SecurityToken.addModule(P_USDTieredSTOFactory.address, bytesSTO, web3.utils.toWei("500"), 0, { from: ISSUER, gasPrice: GAS_PRICE }); + await revertToSnapshot(snapId); + }); + + it("Should allow non-matching beneficiary", async () => { + snapId = await takeSnapshot(); + await I_USDTieredSTO_Array[0].changeAllowBeneficialInvestments(true, { from: ISSUER }); + let allow = await I_USDTieredSTO_Array[0].allowBeneficialInvestments(); + assert.equal(allow, true, "allowBeneficialInvestments should be true"); + }); + + it("Should allow non-matching beneficiary -- failed because it is already active", async () => { + await catchRevert( + I_USDTieredSTO_Array[0].changeAllowBeneficialInvestments(true, { from: ISSUER }) + ); + await revertToSnapshot(snapId); + }); + + it("Should successfully call the modifyTimes before starting the STO -- fail because of bad owner", async() => { + await catchRevert( + I_USDTieredSTO_Array[0].modifyTimes(latestTime() + duration.days(15), latestTime() + duration.days(55), { from: POLYMATH }) + ); + }) + + it("Should successfully call the modifyTimes before starting the STO", async() => { + let snapId = await takeSnapshot(); + let _startTime = latestTime() + duration.days(15); + let _endTime = latestTime() + duration.days(55) + await I_USDTieredSTO_Array[0].modifyTimes(_startTime, _endTime, { from: ISSUER }); + assert.equal(await I_USDTieredSTO_Array[0].startTime.call(), _startTime, "Incorrect _startTime in config"); + assert.equal(await I_USDTieredSTO_Array[0].endTime.call(), _endTime, "Incorrect _endTime in config"); + await revertToSnapshot(snapId); + }); + it("Should successfully attach the second STO module to the security token", async () => { let stoId = 1; // No discount @@ -655,7 +735,7 @@ contract("USDTieredSTO", accounts => { it("Should fail because Zero address is not permitted for wallet", async () => { let stoId = 0; - let wallet = "0x0000000000000000000000000000000000000000"; + let wallet = address_zero; let config = [ _startTime[stoId], _endTime[stoId], @@ -678,7 +758,7 @@ contract("USDTieredSTO", accounts => { it("Should fail because Zero address is not permitted for reserveWallet", async () => { let stoId = 0; - let reserveWallet = "0x0000000000000000000000000000000000000000"; + let reserveWallet = address_zero; let config = [ _startTime[stoId], _endTime[stoId], @@ -815,7 +895,7 @@ contract("USDTieredSTO", accounts => { await I_USDTieredSTO_Array[stoId].modifyAddresses( "0x0000000000000000000000000400000000000000", "0x0000000000000000000003000000000000000000", - "0x0000000000000000000000000000000000000000", + address_zero, { from: ISSUER } ); assert.equal( @@ -830,7 +910,7 @@ contract("USDTieredSTO", accounts => { ); assert.equal( await I_USDTieredSTO_Array[stoId].usdToken.call(), - "0x0000000000000000000000000000000000000000", + address_zero, "STO Configuration doesn't set as expected" ); }); @@ -4229,6 +4309,7 @@ contract("USDTieredSTO", accounts => { assert.equal(await I_USDTieredSTOFactory.getDescription.call(), "USD Tiered STO", "Wrong Module added"); assert.equal(await I_USDTieredSTOFactory.getTitle.call(), "USD Tiered STO", "Wrong Module added"); assert.equal(await I_USDTieredSTOFactory.getInstructions.call(), "Initialises a USD tiered STO.", "Wrong Module added"); + assert.equal(await I_USDTieredSTOFactory.getVersion.call(), "1.0.0"); let tags = await I_USDTieredSTOFactory.getTags.call(); assert.equal(web3.utils.hexToString(tags[0]), "USD"); assert.equal(web3.utils.hexToString(tags[1]), "Tiered"); diff --git a/test/s_v130_to_v140_upgrade.js b/test/s_v130_to_v140_upgrade.js index 8422dc6ee..3fb3092aa 100644 --- a/test/s_v130_to_v140_upgrade.js +++ b/test/s_v130_to_v140_upgrade.js @@ -33,6 +33,7 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { // Initial fee for ticker registry and security token registry const REGFEE = web3.utils.toWei("250"); const STOSetupCost = 0; + const address_zero = "0x0000000000000000000000000000000000000000"; // Module key const STOKEY = 3; @@ -187,7 +188,7 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { console.log(I_POLYOracle.address); assert.notEqual( I_POLYOracle.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "POLYOracle contract was not deployed" ); tx = await I_PolymathRegistry.changeAddress("PolyUsdOracle", I_POLYOracle.address, { from: POLYMATH }); @@ -198,13 +199,13 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { it("Should successfully deploy ETH Oracle and register on PolymathRegistry", async () => { I_USDOracle = await ETHOracle.new( "0x216d678c14be600cb88338e763bb57755ca2b1cf", - "0x0000000000000000000000000000000000000000", + address_zero, "ETH", { from: POLYMATH } ); assert.notEqual( I_USDOracle.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "USDOracle contract was not deployed" ); tx = await I_PolymathRegistry.changeAddress("EthUsdOracle", I_USDOracle.address, { from: POLYMATH }); @@ -227,7 +228,7 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { ); assert.notEqual( I_USDTieredSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "USDTieredSTOFactory contract was not deployed" ); let setupCost = await I_USDTieredSTOFactory.setupCost({ from: POLYMATH }); @@ -249,7 +250,7 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { I_UpgradedCappedSTOFactory = await CappedSTOFactory.new(I_PolyToken.address, STOSetupCost, 0, 0, { from: POLYMATH }); assert.notEqual( I_UpgradedCappedSTOFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "CappedSTOFactory contract was not deployed" ); let setupCost = await I_UpgradedCappedSTOFactory.setupCost({ from: POLYMATH }); @@ -281,7 +282,7 @@ contract("Upgrade from v1.3.0 to v1.4.0", accounts => { }); assert.notEqual( I_ManualApprovalTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "ManualApprovalTransferManagerFactory contract was not deployed" ); }); diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index 2d426d656..40b1cced8 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -257,5 +257,13 @@ contract("SecurityTokenRegistryProxy", accounts => { assert.equal(await readStorage(c.address, 12), I_SecurityTokenRegistry.address, "Implemnted address is not matched"); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); }); + + it("Should get the version", async() => { + assert.equal(await I_SecurityTokenRegistryProxy.version.call({ from: account_polymath_new }), "1.2.0"); + }); + + it("Should get the implementation address", async() => { + assert.equal(await I_SecurityTokenRegistryProxy.implementation.call({ from: account_polymath_new }), I_SecurityTokenRegistry.address); + }) }); }); diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index 4ba4d12c6..6d00b8fe2 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -41,7 +41,7 @@ contract("ModuleRegistryProxy", accounts => { const initRegFee = web3.utils.toWei("250"); const version = "1.0.0"; const message = "Transaction Should Fail!"; - + const address_zero = "0x0000000000000000000000000000000000000000"; // SecurityToken Details for funds raise Type ETH const name = "Team"; const symbol = "SAP"; @@ -128,7 +128,7 @@ contract("ModuleRegistryProxy", accounts => { assert.notEqual( I_GeneralTransferManagerFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "GeneralTransferManagerFactory contract was not deployed" ); @@ -143,7 +143,7 @@ contract("ModuleRegistryProxy", accounts => { assert.notEqual( I_STFactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "STFactory contract was not deployed" ); }); @@ -166,7 +166,7 @@ contract("ModuleRegistryProxy", accounts => { assert.notEqual( I_GeneralPermissionManagerfactory.address.valueOf(), - "0x0000000000000000000000000000000000000000", + address_zero, "GeneralPermissionManagerFactory contract was not deployed" ); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index b1af22535..a8a11f66d 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -51,6 +51,7 @@ contract("TrackedRedemption", accounts => { let I_PolyToken; let I_MRProxied; let I_PolymathRegistry; + let P_TrackedRedemptionFactory; // SecurityToken Details const name = "Team"; @@ -104,6 +105,7 @@ contract("TrackedRedemption", accounts => { // STEP 4: Deploy the TrackedRedemption [I_TrackedRedemptionFactory] = await deployRedemptionAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + [P_TrackedRedemptionFactory] = await deployRedemptionAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, web3.utils.toWei("500")); // Printing all the contract addresses console.log(` @@ -153,6 +155,20 @@ contract("TrackedRedemption", accounts => { I_GeneralTransferManager = GeneralTransferManager.at(moduleData); }); + it("Should successfully attach the paid TrackedRedemption with the security token", async () => { + let snapId = await takeSnapshot(); + await I_PolyToken.getTokens(web3.utils.toWei("500"), I_SecurityToken.address); + const tx = await I_SecurityToken.addModule(P_TrackedRedemptionFactory.address, "", web3.utils.toWei("500"), 0, { from: token_owner }); + assert.equal(tx.logs[3].args._types[0].toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[3].args._name).replace(/\u0000/g, ""), + "TrackedRedemption", + "TrackedRedemption module was not added" + ); + I_TrackedRedemption = TrackedRedemption.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); + }); + it("Should successfully attach the TrackedRedemption with the security token", async () => { const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, "", 0, 0, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); diff --git a/test/w_lockup_volume_restriction_transfer_manager.js b/test/w_lockup_volume_restriction_transfer_manager.js index 1caea7374..fda65be4f 100644 --- a/test/w_lockup_volume_restriction_transfer_manager.js +++ b/test/w_lockup_volume_restriction_transfer_manager.js @@ -359,7 +359,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { it("Should prevent the transfer of tokens in a lockup", async() => { let balance = await I_SecurityToken.balanceOf(account_investor2) - + console.log("balance", balance.dividedBy(new BigNumber(1).times(new BigNumber(10).pow(18))).toNumber()); // create a lockup for their entire balance // over 12 seconds total, with 3 periods of 4 seconds each. await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 12, 4, 0, balance, { from: token_owner }); @@ -377,7 +377,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { it("Should allow the transfer of tokens in a lockup if a period has passed", async() => { // wait 4 seconds - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(duration.seconds(4)); await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('3', 'ether'), { from: account_investor2 }); }); @@ -392,7 +392,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { it("Should allow the transfer of more tokens in a lockup if another period has passed", async() => { // wait 4 more seconds - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(4000); await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('3', 'ether'), { from: account_investor2 }); }); @@ -402,7 +402,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { let balance = await I_SecurityToken.balanceOf(account_investor2) // wait 4 more seconds - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(4000); await I_SecurityToken.transfer(account_investor1, balance, { from: account_investor2 }); }); @@ -453,6 +453,20 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { }); + it("Should succesfully modify the lockup - fail because array index out of bound", async() => { + // balance here should be 12000000000000000000 (12e18 or 12 eth) + let balance = await I_SecurityToken.balanceOf(account_investor1); + await catchRevert( + I_VolumeRestrictionTransferManager.modifyLockUp(account_investor1, 8, 8, 4, 0, balance, { from: token_owner }) + ); + }) + + it("Should succesfully get the lockup - fail because array index out of bound", async() => { + await catchRevert( + I_VolumeRestrictionTransferManager.getLockUp(account_investor1, 9) + ); + }) + it("Should be possible to remove a lockup -- couldn't transfer because of lock up", async() => { let acct1Balance = await I_SecurityToken.balanceOf(account_investor1) @@ -478,6 +492,12 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { assert.equal(acct2BalanceAfter.sub(acct2BalanceBefore).toString(), acct1Balance.toString()) }); + it("Should try to remove the lockup --failed because of index is out of bounds", async() => { + await catchRevert( + I_VolumeRestrictionTransferManager.removeLockUp(account_investor2, 7, { from: token_owner }) + ); + }) + it("Should be possible to create multiple lockups at once", async() => { let balancesBefore = {} @@ -536,7 +556,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { assert.equal(lockUpCountsAfter[account_investor3], 1); // wait 4 seconds - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(4000); // try transfers again await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('2', 'ether'), { from: account_investor2 }); @@ -576,34 +596,27 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { lockUpsLength = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); assert.equal(lockUpsLength, 0); - let now = (await web3.eth.getBlock('latest')).timestamp + let now = latestTime(); // balance here should be 10000000000000000000 let balance = await I_SecurityToken.balanceOf(account_investor2) - await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 100, 10, now + 4, balance, { from: token_owner }); - - // try a transfer. it should fail because the lockup hasn't started yet. - await catchRevert( - I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) - ); - now = (await web3.eth.getBlock('latest')).timestamp + await I_VolumeRestrictionTransferManager.addLockUp(account_investor2, 100, 10, now + duration.seconds(4), balance, { from: token_owner }); // wait 4 seconds for the lockup to begin - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(duration.seconds(4)); // try another transfer. it should also fail because the lockup has just begun await catchRevert( I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), { from: account_investor2 }) ); - now = (await web3.eth.getBlock('latest')).timestamp }); it("Should be possible to edit a lockup with a specific start time in the future", async() => { // edit the lockup - let now = (await web3.eth.getBlock('latest')).timestamp + let now = latestTime(); // should be 10000000000000000000 let balance = await I_SecurityToken.balanceOf(account_investor2) @@ -621,7 +634,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { assert.equal(lockUp[3].toString(), balance.toString()); // edit the lockup - await I_VolumeRestrictionTransferManager.modifyLockUp(account_investor2, 0, 8, 4, now + 4, balance, { from: token_owner }); + await I_VolumeRestrictionTransferManager.modifyLockUp(account_investor2, 0, 8, 4, now + duration.seconds(4), balance, { from: token_owner }); // check and get the lockup again lockUpCount = await I_VolumeRestrictionTransferManager.getLockUpsLength(account_investor2); @@ -641,7 +654,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { ); // wait 4 seconds for the lockup to begin - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(duration.seconds(4)); // try another transfer. it should fail because the lockup has just begun await catchRevert( @@ -649,7 +662,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { ); // wait 4 seconds for the lockup's first period to elapse - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(duration.seconds(4)); // try another transfer. it should pass await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor2 }); @@ -661,7 +674,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { ); // wait 4 seconds for the lockup's first period to elapse - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(duration.seconds(4)); let lockUpBeforeVerify = await I_VolumeRestrictionTransferManager.getLockUp(account_investor2, 0); // check if transfer will pass in read-only operation @@ -676,7 +689,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('5', 'ether'), { from: account_investor2 }); // wait 4 seconds for the lockup's first period to elapse. but, we are all out of periods. - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(duration.seconds(4)); // try one final transfer. this should fail because the user has already withdrawn their entire balance await catchRevert( @@ -702,8 +715,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }) ); // wait 4 seconds for the lockup's first period to elapse. - await new Promise(resolve => setTimeout(resolve, 4000)); - + await increaseTime(duration.seconds(4)); // should succeed await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('2', 'ether'), { from: account_investor1 }); @@ -720,7 +732,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { ); // wait 4 seconds for the 1st lockup's second period to elapse, and the 2nd lockup's first period to elapse - await new Promise(resolve => setTimeout(resolve, 4000)); + await increaseTime(duration.seconds(4)); // should now be able to transfer 4, because of 2 allowed from the 1st lockup and 2 from the 2nd await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); @@ -731,14 +743,12 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { ); // wait 4 seconds for the 1st lockup's final period to elapse, and the 2nd lockup's second period to elapse - await new Promise(resolve => setTimeout(resolve, 4000)); - + await increaseTime(duration.seconds(4)); // should now be able to transfer 4, because of 2 allowed from the 1st lockup and 2 from the 2nd await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); // wait 8 seconds for 2nd lockup's third and fourth periods to elapse - await new Promise(resolve => setTimeout(resolve, 8000)); - + await increaseTime(duration.seconds(8)); // should now be able to transfer 4, because there are 2 allowed per period in the 2nd lockup, and 2 periods have elapsed await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('4', 'ether'), { from: account_investor1 }); @@ -786,7 +796,7 @@ contract('LockupVolumeRestrictionTransferManager', accounts => { assert.equal(await I_VolumeRestrictionTransferManagerFactory.getInstructions.call(), "Allows an issuer to set lockup periods for user addresses, with funds distributed over time. Init function takes no parameters.", "Wrong Module added"); - + assert.equal(await I_VolumeRestrictionTransferManagerFactory.getVersion.call(), "1.0.0"); }); it("Should get the tags of the factory", async() => { diff --git a/test/x_single_trade_volume_restriction.js b/test/x_single_trade_volume_restriction.js index f4bf8180a..a0e1fb3f0 100644 --- a/test/x_single_trade_volume_restriction.js +++ b/test/x_single_trade_volume_restriction.js @@ -277,6 +277,15 @@ contract('SingleTradeVolumeRestrictionManager', accounts => { ); }); + it("Should allow the primary issuance", async() => { + let snapId = await takeSnapshot(); + await I_SingleTradeVolumeRestrictionManager.setAllowPrimaryIssuance(true, {from: token_owner}); + await catchRevert( + I_SingleTradeVolumeRestrictionManager.setAllowPrimaryIssuance(true, {from: token_owner}) + ) + await revertToSnapshot(snapId); + }) + it("add exempt wallet -- Not authorised ", async () => { await catchRevert ( I_SingleTradeVolumeRestrictionManager.addExemptWallet(accounts[5]) From 1a383044a29d91c9fe74cb3627abdd86b8f2e96a Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Tue, 16 Oct 2018 15:16:29 -0700 Subject: [PATCH 137/142] Windows support (#343) * Truffle config rename * Windows support added * Windows test accounts fixed * Added coverage support on windows * patch for solcover solcover * coverage test command changed * Updated coverage script * updated gitignore * Update README.md --- .gitignore | 6 +++++- README.md | 16 ++++++++++++---- package.json | 2 ++ scripts/patch.js | 25 +++++++++++++++++++++++++ scripts/wincov.cmd | 18 ++++++++++++++++++ scripts/wintest.cmd | 24 ++++++++++++++++++++++++ truffle.js => truffle-config.js | 0 7 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 scripts/patch.js create mode 100644 scripts/wincov.cmd create mode 100644 scripts/wintest.cmd rename truffle.js => truffle-config.js (100%) diff --git a/.gitignore b/.gitignore index 5e131eaba..1693ab75c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,8 @@ coverageEnv /flat /tempPoly .eslintrc.js -package-lock.json \ No newline at end of file +package-lock.json +bridge.log +.node-xml* +.solcover.js.bk +allFiredEvents \ No newline at end of file diff --git a/README.md b/README.md index 88f2407ec..98173db84 100644 --- a/README.md +++ b/README.md @@ -208,9 +208,10 @@ node CLI/polymath-cli dividends_manager ## Package version requirements for your machine: -- Homebrew v1.6.7 - node v8.x.x or v9.x.x +- npm v6.x.x or newer - Yarn v1.3 or newer +- Homebrew v1.6.7 (for macOS) - Truffle v4.1.11 (core: 4.1.11) - Solidity v0.4.24 (solc-js) - Ganache CLI v6.1.3 (ganache-core: 2.1.2) or newer @@ -221,10 +222,13 @@ The smart contracts are written in [Solidity](https://github.com/ethereum/solidi ```bash # Install Truffle package globally: -$ yarn global add truffle +$ npm install --global truffle + +# (Only for windows) set up build tools for node-gyp by running below command in powershell: +$ npm install --global --production windows-build-tools # Install local node dependencies: -$ yarn install +$ yarn ``` ## Testing @@ -232,7 +236,11 @@ $ yarn install To test the code simply run: ```bash -$ yarn run test +# on *nix systems +$ npm run test + +# on windows systems +$ npm run wintest ``` diff --git a/package.json b/package.json index f0d2f5ceb..8c322e8c0 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ }, "scripts": { "test": "scripts/test.sh 2> /dev/null", + "wintest": "scripts\\wintest.cmd", + "wincov": "scripts\\wincov.cmd", "docs": "scripts/docs.sh", "lint": "eslint .", "lint:fix": "eslint . --fix", diff --git a/scripts/patch.js b/scripts/patch.js new file mode 100644 index 000000000..b1bbbcb3f --- /dev/null +++ b/scripts/patch.js @@ -0,0 +1,25 @@ +const fs = require('fs'); +const request = require('request'); +const regex = /node ..\/n(.)*,/gmi; +const regex2 = /truffle test(.)*,/gmi; + +request('https://raw.githubusercontent.com/maxsam4/solidity-coverage/relative-path/lib/app.js').pipe(fs.createWriteStream('node_modules\\solidity-coverage\\lib\\app.js')); + +fs.readFile('.solcover.js', 'utf8', function (err,data) { + if (err) { + return console.log(err); + } + + let testCommand = 'truffle test --network coverage'; + fs.readdirSync('./test').forEach(file => { + if(file != 'a_poly_oracle.js' && file != 's_v130_to_v140_upgrade.js') + testCommand = testCommand + ' test\\\\' + file; + }); + testCommand = testCommand + '\','; + let result = data.replace(regex2, testCommand); + result = result.replace(regex, testCommand); + + fs.writeFile('.solcover.js', result, 'utf8', function (err) { + if (err) return console.log(err); + }); +}); \ No newline at end of file diff --git a/scripts/wincov.cmd b/scripts/wincov.cmd new file mode 100644 index 000000000..854e42936 --- /dev/null +++ b/scripts/wincov.cmd @@ -0,0 +1,18 @@ +@echo off + +@SET accounts=--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501202,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501203,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501204,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501205,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501206,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501207,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501208,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501209,1000000000000000000000000" +@START /b node_modules\.bin\testrpc-sc.cmd --gasLimit 0xfffffffffff --defaultBalanceEther 1000000000 --gasPrice 1 --port 8545 %accounts%> %temp%\nul + +@COPY .solcover.js .solcover.js.bk +node scripts\patch.js +node_modules\.bin\solidity-coverage.cmd +@MOVE /y .solcover.js.bk .solcover.js diff --git a/scripts/wintest.cmd b/scripts/wintest.cmd new file mode 100644 index 000000000..e5a2a6a61 --- /dev/null +++ b/scripts/wintest.cmd @@ -0,0 +1,24 @@ +@echo off + +@SET accounts=--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501202,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501203,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501204,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501205,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501206,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501207,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501208,1000000000000000000000000" ^ +--account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501209,1000000000000000000000000" +@START /b node_modules\.bin\ganache-cli.cmd --gasLimit 8000000 --defaultBalanceEther 1000000000 --gasPrice 1 %accounts%> %temp%\nul +@SET var=truffle test + +for %%i in (test\*.js) do call :PushTest %%i +%var% + +:PushTest +if NOT "%1" == "test\a_poly_oracle.js" ( + if NOT "%1" == "test\s_v130_to_v140_upgrade.js" ( + set var=%var% %1 + ) +) diff --git a/truffle.js b/truffle-config.js similarity index 100% rename from truffle.js rename to truffle-config.js From ac8630c8f1636fa12478563f6569502a18accfdc Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Wed, 17 Oct 2018 07:17:50 -0700 Subject: [PATCH 138/142] Dividend delegate (#344) * WIP * Added/updated test cases * Added test cases --- .../modules/Checkpoint/DividendCheckpoint.sol | 10 +- .../Checkpoint/ERC20DividendCheckpoint.sol | 12 +- .../Checkpoint/EtherDividendCheckpoint.sol | 12 +- test/e_erc20_dividends.js | 221 +++++++++++++++++- test/f_ether_dividends.js | 150 +++++++++++- 5 files changed, 384 insertions(+), 21 deletions(-) diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 2235dc056..240295c1e 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -15,6 +15,7 @@ contract DividendCheckpoint is ICheckpoint, Module { uint256 public EXCLUDED_ADDRESS_LIMIT = 50; bytes32 public constant DISTRIBUTE = "DISTRIBUTE"; + bytes32 public constant MANAGE = "MANAGE"; struct Dividend { uint256 checkpointId; @@ -76,7 +77,7 @@ contract DividendCheckpoint is ICheckpoint, Module { * @notice Function to clear and set list of excluded addresses used for future dividends * @param _excluded addresses of investor */ - function setDefaultExcluded(address[] _excluded) public onlyOwner { + function setDefaultExcluded(address[] _excluded) public withPerm(MANAGE) { require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many excluded addresses"); excluded = _excluded; emit SetDefaultExcludedAddresses(excluded, now); @@ -87,7 +88,7 @@ contract DividendCheckpoint is ICheckpoint, Module { * @param _investors addresses of investor * @param _withholding withholding tax for individual investors (multiplied by 10**16) */ - function setWithholding(address[] _investors, uint256[] _withholding) public onlyOwner { + function setWithholding(address[] _investors, uint256[] _withholding) public withPerm(MANAGE) { require(_investors.length == _withholding.length, "Mismatched input lengths"); emit SetWithholding(_investors, _withholding, now); for (uint256 i = 0; i < _investors.length; i++) { @@ -101,7 +102,7 @@ contract DividendCheckpoint is ICheckpoint, Module { * @param _investors addresses of investor * @param _withholding withholding tax for all investors (multiplied by 10**16) */ - function setWithholdingFixed(address[] _investors, uint256 _withholding) public onlyOwner { + function setWithholdingFixed(address[] _investors, uint256 _withholding) public withPerm(MANAGE) { require(_withholding <= 10**18, "Incorrect withholding tax"); emit SetWithholdingFixed(_investors, _withholding, now); for (uint256 i = 0; i < _investors.length; i++) { @@ -220,8 +221,9 @@ contract DividendCheckpoint is ICheckpoint, Module { * @return bytes32 array */ function getPermissions() public view returns(bytes32[]) { - bytes32[] memory allPermissions = new bytes32[](1); + bytes32[] memory allPermissions = new bytes32[](2); allPermissions[0] = DISTRIBUTE; + allPermissions[1] = MANAGE; return allPermissions; } diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol index 60d84a41b..fa73b736d 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol @@ -35,7 +35,7 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { * @param _amount Amount of specified token for dividend * @param _name name/title for identification */ - function createDividend(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, bytes32 _name) external onlyOwner { + function createDividend(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, bytes32 _name) external withPerm(MANAGE) { createDividendWithExclusions(_maturity, _expiry, _token, _amount, excluded, _name); } @@ -48,7 +48,7 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { * @param _checkpointId Checkpoint id from which to create dividends * @param _name name/title for identification */ - function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, uint256 _checkpointId, bytes32 _name) external onlyOwner { + function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, uint256 _checkpointId, bytes32 _name) external withPerm(MANAGE) { _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, _checkpointId, excluded, _name); } @@ -61,7 +61,7 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { * @param _excluded List of addresses to exclude * @param _name name/title for identification */ - function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, address[] _excluded, bytes32 _name) public onlyOwner { + function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address _token, uint256 _amount, address[] _excluded, bytes32 _name) public withPerm(MANAGE) { uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, checkpointId, _excluded, _name); } @@ -86,7 +86,7 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { bytes32 _name ) public - onlyOwner + withPerm(MANAGE) { _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _token, _amount, _checkpointId, _excluded, _name); } @@ -179,7 +179,7 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends * @param _dividendIndex Dividend to reclaim */ - function reclaimDividend(uint256 _dividendIndex) external onlyOwner { + function reclaimDividend(uint256 _dividendIndex) external withPerm(MANAGE) { require(_dividendIndex < dividends.length, "Incorrect dividend index"); require(now >= dividends[_dividendIndex].expiry, "Dividend expiry is in the future"); require(!dividends[_dividendIndex].reclaimed, "Dividend already claimed"); @@ -194,7 +194,7 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { * @notice Allows issuer to withdraw withheld tax * @param _dividendIndex Dividend to withdraw from */ - function withdrawWithholding(uint256 _dividendIndex) external onlyOwner { + function withdrawWithholding(uint256 _dividendIndex) external withPerm(MANAGE) { require(_dividendIndex < dividends.length, "Incorrect dividend index"); Dividend storage dividend = dividends[_dividendIndex]; uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol index 0d5e3fbf2..8bef941dd 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol @@ -30,7 +30,7 @@ contract EtherDividendCheckpoint is DividendCheckpoint { * @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer * @param _name name/title for identification */ - function createDividend(uint256 _maturity, uint256 _expiry, bytes32 _name) payable external onlyOwner { + function createDividend(uint256 _maturity, uint256 _expiry, bytes32 _name) payable external withPerm(MANAGE) { createDividendWithExclusions(_maturity, _expiry, excluded, _name); } @@ -41,7 +41,7 @@ contract EtherDividendCheckpoint is DividendCheckpoint { * @param _checkpointId Id of the checkpoint from which to issue dividend * @param _name name/title for identification */ - function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, uint256 _checkpointId, bytes32 _name) payable external onlyOwner { + function createDividendWithCheckpoint(uint256 _maturity, uint256 _expiry, uint256 _checkpointId, bytes32 _name) payable external withPerm(MANAGE) { _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _checkpointId, excluded, _name); } @@ -52,7 +52,7 @@ contract EtherDividendCheckpoint is DividendCheckpoint { * @param _excluded List of addresses to exclude * @param _name name/title for identification */ - function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address[] _excluded, bytes32 _name) payable public onlyOwner { + function createDividendWithExclusions(uint256 _maturity, uint256 _expiry, address[] _excluded, bytes32 _name) payable public withPerm(MANAGE) { uint256 checkpointId = ISecurityToken(securityToken).createCheckpoint(); _createDividendWithCheckpointAndExclusions(_maturity, _expiry, checkpointId, _excluded, _name); } @@ -74,7 +74,7 @@ contract EtherDividendCheckpoint is DividendCheckpoint { ) payable public - onlyOwner + withPerm(MANAGE) { _createDividendWithCheckpointAndExclusions(_maturity, _expiry, _checkpointId, _excluded, _name); } @@ -156,7 +156,7 @@ contract EtherDividendCheckpoint is DividendCheckpoint { * @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends * @param _dividendIndex Dividend to reclaim */ - function reclaimDividend(uint256 _dividendIndex) external onlyOwner { + function reclaimDividend(uint256 _dividendIndex) external withPerm(MANAGE) { require(_dividendIndex < dividends.length, "Incorrect dividend index"); require(now >= dividends[_dividendIndex].expiry, "Dividend expiry is in the future"); require(!dividends[_dividendIndex].reclaimed, "Dividend already claimed"); @@ -171,7 +171,7 @@ contract EtherDividendCheckpoint is DividendCheckpoint { * @notice Allows issuer to withdraw withheld tax * @param _dividendIndex Dividend to withdraw from */ - function withdrawWithholding(uint256 _dividendIndex) external onlyOwner { + function withdrawWithholding(uint256 _dividendIndex) external withPerm(MANAGE) { require(_dividendIndex < dividends.length, "Incorrect dividend index"); Dividend storage dividend = dividends[_dividendIndex]; uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index ac690b8ae..b0ba2e4e9 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -2,11 +2,12 @@ import latestTime from "./helpers/latestTime"; import { duration, promisifyLogWatch, latestBlock } from "./helpers/utils"; import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork, deployERC20DividendAndVerifyed } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployERC20DividendAndVerifyed, deployGPMAndVerifyed } from "./helpers/createInstances"; const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const ERC20DividendCheckpoint = artifacts.require("./ERC20DividendCheckpoint"); +const GeneralPermissionManager = artifacts.require("GeneralPermissionManager"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -21,6 +22,7 @@ contract("ERC20DividendCheckpoint", accounts => { let account_investor2; let account_investor3; let account_investor4; + let account_manager; let account_temp; // investor Details @@ -38,6 +40,7 @@ contract("ERC20DividendCheckpoint", accounts => { let P_ERC20DividendCheckpointFactory; let P_ERC20DividendCheckpoint; let I_GeneralPermissionManager; + let I_GeneralPermissionManagerFactory; let I_ERC20DividendCheckpoint; let I_GeneralTransferManager; let I_ExchangeTransferManager; @@ -65,9 +68,14 @@ contract("ERC20DividendCheckpoint", accounts => { const stoKey = 3; const checkpointKey = 4; + //Manager details + const managerDetails = "Hello, I am a legit manager"; + // Initial fee for ticker registry and security token registry const initRegFee = web3.utils.toWei("250"); + const zero_address = '0x0000000000000000000000000000000000000000'; + before(async () => { // Accounts setup account_polymath = accounts[0]; @@ -80,7 +88,8 @@ contract("ERC20DividendCheckpoint", accounts => { account_investor3 = accounts[8]; account_investor4 = accounts[9]; account_temp = accounts[2]; - + account_manager = accounts[5]; + // Step 1: Deploy the genral PM ecosystem let instances = await setUpPolymathNetwork(account_polymath, token_owner); @@ -816,7 +825,213 @@ contract("ERC20DividendCheckpoint", accounts => { it("Should get the listed permissions", async () => { let tx = await I_ERC20DividendCheckpoint.getPermissions.call(); - assert.equal(tx.length, 1); + assert.equal(tx.length, 2); + }); + + it("should registr a delegate", async () => { + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), + "GeneralPermissionManager", + "GeneralPermissionManagerFactory module was not added" + ); + I_GeneralPermissionManager = await GeneralPermissionManager.at(tx.logs[2].args._module); + tx = await I_GeneralPermissionManager.addDelegate(account_manager, managerDetails, { from: token_owner}); + assert.equal(tx.logs[0].args._delegate, account_manager); + }); + + it("should not allow manager without permission to set default excluded", async () => { + await catchRevert(I_ERC20DividendCheckpoint.setDefaultExcluded( + [0], + { from: account_manager } + )); + }); + + it("should not allow manager without permission to set withholding", async () => { + await catchRevert(I_ERC20DividendCheckpoint.setWithholding( + [0], + [0], + { from: account_manager } + )); + }); + + it("should not allow manager without permission to set withholding fixed", async () => { + await catchRevert(I_ERC20DividendCheckpoint.setWithholdingFixed( + [0], + 0, + { from: account_manager } + )); + }); + + it("should not allow manager without permission to create dividend", async () => { + await I_PolyToken.transfer(account_manager, web3.utils.toWei("100", "ether"), { from: token_owner }); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei("100", "ether"), { from: account_manager }); + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + + await catchRevert(I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + dividendName, + { from: account_manager } + )); + }); + + it("should not allow manager without permission to create dividend with checkpoint", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + await catchRevert(I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + checkpointID.toNumber(), + dividendName, + { from: account_manager } + )); + }); + + it("should not allow manager without permission to create dividend with exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + await catchRevert(I_ERC20DividendCheckpoint.createDividendWithExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + exclusions, + dividendName, + { from: account_manager } + )); + }); + + it("should not allow manager without permission to create dividend with checkpoint and exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + await catchRevert(I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + checkpointID.toNumber(), + exclusions, + dividendName, + { from: account_manager } + )); + }); + + it("should give permission to manager", async () => { + let tx = await I_GeneralPermissionManager.changePermission( + account_manager, + I_ERC20DividendCheckpoint.address, + "MANAGE", + true, + { from: token_owner } + ); + assert.equal(tx.logs[0].args._delegate, account_manager); + }); + + it("should allow manager with permission to set default excluded", async () => { + let tx = await I_ERC20DividendCheckpoint.setDefaultExcluded( + [0], + { from: account_manager } + ); + assert.equal(tx.logs[0].args._excluded[0], zero_address); + }); + + it("should allow manager with permission to set withholding", async () => { + let tx = await I_ERC20DividendCheckpoint.setWithholding( + [0], + [0], + { from: account_manager } + ); + assert.equal(tx.logs[0].args._withholding[0], 0); + }); + + it("should allow manager withpermission to set withholding fixed", async () => { + let tx = await I_ERC20DividendCheckpoint.setWithholdingFixed( + [0], + 0, + { from: account_manager } + ); + assert.equal(tx.logs[0].args._withholding, 0); + }); + + it("should allow manager with permission to create dividend", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + + let tx = await I_ERC20DividendCheckpoint.createDividend( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + dividendName, + { from: account_manager } + ); + assert.equal(tx.logs[0].args._name.toString(), dividendName); + }); + + it("should allow manager with permission to create dividend with checkpoint", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + checkpointID.toNumber(), + dividendName, + { from: account_manager } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 8); + }); + + it("should allow manager with permission to create dividend with exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + let tx = await I_ERC20DividendCheckpoint.createDividendWithExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + exclusions, + dividendName, + { from: account_manager } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 9); + }); + + it("should allow manager with permission to create dividend with checkpoint and exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + let tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + I_PolyToken.address, + web3.utils.toWei("1.5", "ether"), + checkpointID.toNumber(), + exclusions, + dividendName, + { from: account_manager } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 10); }); describe("Test cases for the ERC20DividendCheckpointFactory", async () => { diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 46d5d6a35..8b3255a71 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -3,11 +3,12 @@ import { duration, ensureException, promisifyLogWatch, latestBlock } from "./hel import takeSnapshot, { increaseTime, revertToSnapshot } from "./helpers/time"; import { encodeProxyCall } from "./helpers/encodeCall"; import { catchRevert } from "./helpers/exceptions"; -import { setUpPolymathNetwork, deployEtherDividendAndVerifyed } from "./helpers/createInstances"; +import { setUpPolymathNetwork, deployEtherDividendAndVerifyed, deployGPMAndVerifyed } from "./helpers/createInstances"; const SecurityToken = artifacts.require("./SecurityToken.sol"); const GeneralTransferManager = artifacts.require("./GeneralTransferManager"); const EtherDividendCheckpoint = artifacts.require("./EtherDividendCheckpoint"); +const GeneralPermissionManager = artifacts.require("GeneralPermissionManager"); const Web3 = require("web3"); const BigNumber = require("bignumber.js"); @@ -22,6 +23,7 @@ contract("EtherDividendCheckpoint", accounts => { let account_investor2; let account_investor3; let account_investor4; + let account_manager; let account_temp; // investor Details @@ -39,6 +41,7 @@ contract("EtherDividendCheckpoint", accounts => { let P_EtherDividendCheckpoint; let I_EtherDividendCheckpointFactory; let I_GeneralPermissionManager; + let I_GeneralPermissionManagerFactory; let I_EtherDividendCheckpoint; let I_GeneralTransferManager; let I_ModuleRegistryProxy; @@ -58,6 +61,7 @@ contract("EtherDividendCheckpoint", accounts => { const tokenDetails = "This is equity type of issuance"; const decimals = 18; const contact = "team@polymath.network"; + const managerDetails = "Hello, I am a legit manager"; let snapId; // Module key const delegateManagerKey = 1; @@ -79,6 +83,7 @@ contract("EtherDividendCheckpoint", accounts => { account_investor2 = accounts[7]; account_investor3 = accounts[8]; account_investor4 = accounts[9]; + account_manager = accounts[5]; account_temp = accounts[2]; // Step 1: Deploy the genral PM ecosystem @@ -754,7 +759,148 @@ contract("EtherDividendCheckpoint", accounts => { it("Should get the listed permissions", async () => { let tx = await I_EtherDividendCheckpoint.getPermissions.call(); - assert.equal(tx.length, 1); + assert.equal(tx.length, 2); + }); + + it("should registr a delegate", async () => { + [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, I_PolyToken.address, 0); + let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); + assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); + assert.equal( + web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), + "GeneralPermissionManager", + "GeneralPermissionManagerFactory module was not added" + ); + I_GeneralPermissionManager = await GeneralPermissionManager.at(tx.logs[2].args._module); + tx = await I_GeneralPermissionManager.addDelegate(account_manager, managerDetails, { from: token_owner}); + assert.equal(tx.logs[0].args._delegate, account_manager); + }); + + it("should not allow manager without permission to create dividend", async () => { + await I_PolyToken.transfer(account_manager, web3.utils.toWei("2", "ether"), { from: token_owner }); + await I_PolyToken.approve(I_EtherDividendCheckpoint.address, web3.utils.toWei("1.5", "ether"), { from: account_manager }); + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + + await catchRevert(I_EtherDividendCheckpoint.createDividend( + maturity, + expiry, + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + )); + }); + + it("should not allow manager without permission to create dividend with checkpoint", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + checkpointID.toNumber(), + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + )); + }); + + it("should not allow manager without permission to create dividend with exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + await catchRevert(I_EtherDividendCheckpoint.createDividendWithExclusions( + maturity, + expiry, + exclusions, + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + )); + }); + + it("should not allow manager without permission to create dividend with checkpoint and exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + await catchRevert(I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + checkpointID.toNumber(), + exclusions, + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + )); + }); + + it("should give permission to manager", async () => { + let tx = await I_GeneralPermissionManager.changePermission( + account_manager, + I_EtherDividendCheckpoint.address, + "MANAGE", + true, + { from: token_owner } + ); + assert.equal(tx.logs[0].args._delegate, account_manager); + }); + + it("should allow manager with permission to create dividend", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + + let tx = await I_EtherDividendCheckpoint.createDividend( + maturity, + expiry, + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 9); + }); + + it("should allow manager with permission to create dividend with checkpoint", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpoint( + maturity, + expiry, + checkpointID.toNumber(), + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 10); + }); + + it("should allow manager with permission to create dividend with exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + let tx = await I_EtherDividendCheckpoint.createDividendWithExclusions( + maturity, + expiry, + exclusions, + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 11); + }); + + it("should allow manager with permission to create dividend with checkpoint and exclusion", async () => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let exclusions = [0]; + let checkpointID = await I_SecurityToken.createCheckpoint.call({ from: token_owner }); + await I_SecurityToken.createCheckpoint({ from: token_owner }); + let tx = await I_EtherDividendCheckpoint.createDividendWithCheckpointAndExclusions( + maturity, + expiry, + checkpointID.toNumber(), + exclusions, + dividendName, + { from: account_manager, value: web3.utils.toWei("12", "ether") } + ); + assert.equal(tx.logs[0].args._checkpointId.toNumber(), 12); }); describe("Test cases for the EtherDividendCheckpointFactory", async () => { From 37df18ce43909520bc0413f4a549f6666a694790 Mon Sep 17 00:00:00 2001 From: Victor Vicente Date: Thu, 18 Oct 2018 09:15:06 -0300 Subject: [PATCH 139/142] CLI typos fix * Fix typos found by Charles --- CLI/commands/ST20Generator.js | 8 ++++---- CLI/commands/contract_manager.js | 12 ++++++------ CLI/commands/dividends_manager.js | 4 ++-- CLI/commands/faucet.js | 2 +- CLI/commands/investor_portal.js | 2 +- CLI/commands/module_manager.js | 2 +- CLI/commands/permission_manager.js | 2 +- CLI/commands/transfer.js | 2 +- CLI/commands/transfer_manager.js | 7 ++++--- CLI/commands/transfer_ownership.js | 2 +- test/b_capped_sto.js | 2 +- test/g_general_permission_manager.js | 2 +- test/m_presale_sto.js | 2 +- 13 files changed, 25 insertions(+), 24 deletions(-) diff --git a/CLI/commands/ST20Generator.js b/CLI/commands/ST20Generator.js index 530da89bb..630d2e1fc 100644 --- a/CLI/commands/ST20Generator.js +++ b/CLI/commands/ST20Generator.js @@ -102,7 +102,7 @@ async function setup(){ } async function step_ticker_reg(){ - console.log('\n\x1b[34m%s\x1b[0m',"Token Creation - Symbol Registration"); + console.log('\n\x1b[34m%s\x1b[0m',"Token Symbol Registration"); let available = false; let regFee = web3.utils.fromWei(await securityTokenRegistry.methods.getTickerRegistrationFee().call()); @@ -208,7 +208,7 @@ async function step_Wallet_Issuance(){ console.log("\n"); console.log('\x1b[34m%s\x1b[0m',"Token Creation - Token Minting for Issuer"); - console.log("Before setting up the STO, you can mint any amount of tokens that will remain under your control or you can trasfer to affiliates"); + console.log("Before setting up the STO, you can mint any amount of tokens that will remain under your control or you can transfer to affiliates"); let multimint; if (typeof _mintingConfig !== 'undefined' && _mintingConfig.hasOwnProperty('multimint')) { @@ -266,7 +266,7 @@ async function multi_mint_tokens() { console.log(chalk.red(`WARNING: `) + `Please make sure all the addresses that get whitelisted are only eligible to hold or get Security token\n`); shell.exec(`${__dirname}/scripts//script.sh Multimint ${tokenSymbol} 75 ${network}`); - console.log(chalk.green(`\nHurray!! Tokens get successfully Minted and transfered to token holders`)); + console.log(chalk.green(`\nHurray!! Tokens get successfully Minted and transferred to token holders`)); } async function step_STO_launch() { @@ -730,7 +730,7 @@ function limitsConfigUSDTieredSTO() { if (typeof _stoConfig !== 'undefined' && _stoConfig.hasOwnProperty('nonAccreditedLimitUSD')) { limits.nonAccreditedLimitUSD = web3.utils.toWei(_stoConfig.nonAccreditedLimitUSD.toString()); } else { - limits.nonAccreditedLimitUSD = web3.utils.toWei(readlineSync.question(`What is the default limit for non accredited insvestors in USD? (${nonAccreditedLimit}): `, { + limits.nonAccreditedLimitUSD = web3.utils.toWei(readlineSync.question(`What is the default limit for non accredited investors in USD? (${nonAccreditedLimit}): `, { limit: function(input) { return new BigNumber(web3.utils.toWei(input)).gte(limits.minimumInvestmentUSD); }, diff --git a/CLI/commands/contract_manager.js b/CLI/commands/contract_manager.js index 594522f6f..bea83ce7d 100644 --- a/CLI/commands/contract_manager.js +++ b/CLI/commands/contract_manager.js @@ -109,7 +109,7 @@ async function strActions() { let tickerStatus = readlineSync.keyInYNStrict(`Is the token deployed?`); let modifyTickerAction = currentContract.methods.modifyTicker(tickerOwner, tickerToModify, tickerSTName, tickerRegistrationDate, tickerExpiryDate, tickerStatus); await common.sendTransaction(Issuer, modifyTickerAction, defaultGasPrice, 0, 1.5); - console.log(chalk.green(`Ticker has been updated successfuly`)); + console.log(chalk.green(`Ticker has been updated successfully`)); break; case 'Remove Ticker': let tickerToRemove = readlineSync.question('Enter the token symbol that you want to remove: '); @@ -119,7 +119,7 @@ async function strActions() { } else { let removeTickerAction = currentContract.methods.removeTicker(tickerToRemove); await common.sendTransaction(Issuer, removeTickerAction, defaultGasPrice, 0, 3); - console.log(chalk.green(`Ticker has been removed successfuly`)); + console.log(chalk.green(`Ticker has been removed successfully`)); } break; case 'Modify SecurityToken': @@ -160,7 +160,7 @@ async function strActions() { let deployedAt = readlineSync.questionInt(`Enter the Unix Epoch timestamp at which security token was deployed: `); let modifySTAction = currentContract.methods.modifySecurityToken(name, ticker, owner, stAddress, tokenDetails, deployedAt); await common.sendTransaction(Issuer, modifySTAction, defaultGasPrice, 0, 1.5); - console.log(chalk.green(`Security Token has been updated successfuly`)); + console.log(chalk.green(`Security Token has been updated successfully`)); break; case 'Change Expiry Limit': let currentExpiryLimit = await currentContract.methods.getExpiryLimit().call(); @@ -169,7 +169,7 @@ async function strActions() { let changeExpiryLimitAction = currentContract.methods.changeExpiryLimit(newExpiryLimit); let changeExpiryLimitReceipt = await common.sendTransaction(Issuer, changeExpiryLimitAction, defaultGasPrice); let changeExpiryLimitEvent = common.getEventFromLogs(currentContract._jsonInterface, changeExpiryLimitReceipt.logs, 'ChangeExpiryLimit'); - console.log(chalk.green(`Expiry limit was changed successfuly. New limit is ${Math.floor(parseInt(changeExpiryLimitEvent._newExpiry)/60/60/24)} days\n`)); + console.log(chalk.green(`Expiry limit was changed successfully. New limit is ${Math.floor(parseInt(changeExpiryLimitEvent._newExpiry)/60/60/24)} days\n`)); break; case 'Change registration fee': let currentRegFee = web3.utils.fromWei(await currentContract.methods.getTickerRegistrationFee().call()); @@ -178,7 +178,7 @@ async function strActions() { let changeRegFeeAction = currentContract.methods.changeTickerRegistrationFee(newRegFee); let changeRegFeeReceipt = await common.sendTransaction(Issuer, changeRegFeeAction, defaultGasPrice); let changeRegFeeEvent = common.getEventFromLogs(currentContract._jsonInterface, changeRegFeeReceipt.logs, 'ChangeTickerRegistrationFee'); - console.log(chalk.green(`Fee was changed successfuly. New fee is ${web3.utils.fromWei(changeRegFeeEvent._newFee)} POLY\n`)); + console.log(chalk.green(`Fee was changed successfully. New fee is ${web3.utils.fromWei(changeRegFeeEvent._newFee)} POLY\n`)); break; case 'Change ST launch fee': let currentLaunchFee = web3.utils.fromWei(await currentContract.methods.getSecurityTokenLaunchFee().call()); @@ -187,7 +187,7 @@ async function strActions() { let changeLaunchFeeAction = currentContract.methods.changeSecurityLaunchFee(newLaunchFee); let changeLaunchFeeReceipt = await common.sendTransaction(Issuer, changeLaunchFeeAction, defaultGasPrice); let changeLaunchFeeEvent = common.getEventFromLogs(currentContract._jsonInterface, changeLaunchFeeReceipt.logs, 'ChangeSecurityLaunchFee'); - console.log(chalk.green(`Fee was changed successfuly. New fee is ${web3.utils.fromWei(changeLaunchFeeEvent._newFee)} POLY\n`)); + console.log(chalk.green(`Fee was changed successfully. New fee is ${web3.utils.fromWei(changeLaunchFeeEvent._newFee)} POLY\n`)); break; case 'CANCEL': process.exit(0); diff --git a/CLI/commands/dividends_manager.js b/CLI/commands/dividends_manager.js index fc9caab4e..bde3aa900 100644 --- a/CLI/commands/dividends_manager.js +++ b/CLI/commands/dividends_manager.js @@ -221,7 +221,7 @@ async function transferTokens(address, amount){ let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'Transfer'); console.log(` Account ${event.from} - transfered ${web3.utils.fromWei(event.value)} tokens + transferred ${web3.utils.fromWei(event.value)} tokens to account ${event.to}` ); } catch (err) { @@ -262,7 +262,7 @@ async function setDefaultExclusions() { let setDefaultExclusionsActions = currentDividendsModule.methods.setDefaultExcluded(excluded); let receipt = await common.sendTransaction(Issuer, setDefaultExclusionsActions, defaultGasPrice); let event = common.getEventFromLogs(currentDividendsModule._jsonInterface, receipt.logs, 'SetDefaultExcludedAddresses'); - console.log(chalk.green(`Exclusions were successfuly set.`)); + console.log(chalk.green(`Exclusions were successfully set.`)); showExcluded(event._excluded); } } diff --git a/CLI/commands/faucet.js b/CLI/commands/faucet.js index 24d1c009d..556ffa402 100644 --- a/CLI/commands/faucet.js +++ b/CLI/commands/faucet.js @@ -43,7 +43,7 @@ async function setup(){ async function send_poly(beneficiary, amount) { let issuerBalance = await polyToken.methods.balanceOf(Issuer.address).call({from : Issuer.address}); - console.log(chalk.blue(`Hello user you have '${(new BigNumber(issuerBalance).dividedBy(new BigNumber(10).pow(18))).toNumber()} POLY'\n`)) + console.log(chalk.blue(`Hello User, your current balance is '${(new BigNumber(issuerBalance).dividedBy(new BigNumber(10).pow(18))).toNumber()} POLY'\n`)) if (typeof beneficiary === 'undefined' && typeof amount === 'undefined') { let options = ['250 POLY for ticker registration','500 POLY for token launch + ticker reg', '20K POLY for CappedSTO Module', diff --git a/CLI/commands/investor_portal.js b/CLI/commands/investor_portal.js index fd308138d..eb339787c 100644 --- a/CLI/commands/investor_portal.js +++ b/CLI/commands/investor_portal.js @@ -495,7 +495,7 @@ async function investUsdTieredSTO(currency, amount) { let approveAction = polyToken.methods.approve(STOAddress, costWei); await common.sendTransaction(User, approveAction, defaultGasPrice); } - let actionBuyWithPoly = currentSTO.methods.buyWithPOLY(User.address, costWei); + let actionBuyWithPoly = currentSTO.methods.buyWithPOLY(User.address, costWei, 0, 1.5); let receipt = await common.sendTransaction(User, actionBuyWithPoly, defaultGasPrice); logTokensPurchasedUSDTieredSTO(receipt); } else { diff --git a/CLI/commands/module_manager.js b/CLI/commands/module_manager.js index 2360e39dc..b91541a9c 100644 --- a/CLI/commands/module_manager.js +++ b/CLI/commands/module_manager.js @@ -279,7 +279,7 @@ async function archiveModule() { pushModules(stoModules); pushModules(cpModules); - let index = readlineSync.keyInSelect(options, chalk.yellow('Which module whould you like to archive?')); + let index = readlineSync.keyInSelect(options, chalk.yellow('Which module would you like to archive?')); if (index != -1) { console.log("\nSelected: ",options[index]); let archiveModuleAction = securityToken.methods.archiveModule(modules[index].module.address); diff --git a/CLI/commands/permission_manager.js b/CLI/commands/permission_manager.js index 49a20f7e3..f567aaa4d 100644 --- a/CLI/commands/permission_manager.js +++ b/CLI/commands/permission_manager.js @@ -147,7 +147,7 @@ function isPermissionValid() { async function changePermission(delegate, moduleAddress, permission, isValid) { let changePermissionAction = generalPermissionManager.methods.changePermission(delegate, moduleAddress, web3.utils.asciiToHex(permission), isValid); - let receipt = await common.sendTransaction(Issuer, changePermissionAction, defaultGasPrice, 0, 1.5); + let receipt = await common.sendTransaction(Issuer, changePermissionAction, defaultGasPrice, 0, 2); common.getEventFromLogs(generalPermissionManager._jsonInterface, receipt.logs, 'ChangePermission'); console.log(`Permission changed succesfully,`); } diff --git a/CLI/commands/transfer.js b/CLI/commands/transfer.js index d34176f23..48fbb79e5 100644 --- a/CLI/commands/transfer.js +++ b/CLI/commands/transfer.js @@ -50,7 +50,7 @@ async function transfer() { let event = common.getEventFromLogs(securityToken._jsonInterface, receipt.logs, 'Transfer'); console.log(` Account ${event.from} - transfered ${web3.utils.fromWei(event.value,"ether")} tokens + transferred ${web3.utils.fromWei(event.value,"ether")} tokens to account ${event.to}` ); } catch (err){ diff --git a/CLI/commands/transfer_manager.js b/CLI/commands/transfer_manager.js index 0769f88aa..df06c68f4 100644 --- a/CLI/commands/transfer_manager.js +++ b/CLI/commands/transfer_manager.js @@ -111,11 +111,12 @@ async function start_explorer() { }, limitMessage: `Amount must be less or equal than ${fromBalance} ${tokenSymbol}`, }); - let data = readlineSync.question('Enter the data attached to the transfer by controller to emit in event: '); - let forceTransferAction = securityToken.methods.forceTransfer(from, to, web3.utils.toWei(amount), web3.utils.asciiToHex(data)); + let data = readlineSync.question('Enter the data to indicate validation: '); + let log = readlineSync.question('Enter the data attached to the transfer by controller to emit in event: '); + let forceTransferAction = securityToken.methods.forceTransfer(from, to, web3.utils.toWei(amount), web3.utils.asciiToHex(data), web3.utils.asciiToHex(log)); let forceTransferReceipt = await common.sendTransaction(Issuer, forceTransferAction, defaultGasPrice, 0, 1.5); let forceTransferEvent = common.getEventFromLogs(securityToken._jsonInterface, forceTransferReceipt.logs, 'ForceTransfer'); - console.log(chalk.green(` ${forceTransferEvent._controller} has successfully forced a transfer of ${web3.utils.fromWei(forceTransferEvent._amount)} ${tokenSymbol} + console.log(chalk.green(` ${forceTransferEvent._controller} has successfully forced a transfer of ${web3.utils.fromWei(forceTransferEvent._value)} ${tokenSymbol} from ${forceTransferEvent._from} to ${forceTransferEvent._to} Verified transfer: ${forceTransferEvent._verifyTransfer} Data: ${web3.utils.hexToAscii(forceTransferEvent._data)} diff --git a/CLI/commands/transfer_ownership.js b/CLI/commands/transfer_ownership.js index 67f49ec63..68ca7eb7a 100644 --- a/CLI/commands/transfer_ownership.js +++ b/CLI/commands/transfer_ownership.js @@ -30,7 +30,7 @@ async function transferOwnership(transferTo) { let transferOwnershipAction = contract.methods.transferOwnership(transferTo); let receipt = await common.sendTransaction(Issuer, transferOwnershipAction, defaultGasPrice); let event = common.getEventFromLogs(contract._jsonInterface, receipt.logs, 'OwnershipTransferred'); - console.log(chalk.green(`Ownership transferred successfuly. New owner is ${event.newOwner}`)); + console.log(chalk.green(`Ownership transferred successfully. New owner is ${event.newOwner}`)); } }; diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index ff80f1025..58d2335d3 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -510,7 +510,7 @@ contract("CappedSTO", accounts => { assert.equal( (await I_PolyToken.balanceOf(account_investor1)).toNumber(), initInvestorBalance.toNumber(), - "tokens are not transfered out from investor account" + "tokens are not transferred out from investor account" ); assert.equal( (await I_PolyToken.balanceOf(token_owner)).toNumber(), diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index eb22406c8..231cefe70 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -220,7 +220,7 @@ contract('GeneralPermissionManager', accounts => { ); }); - it("Should successfuly add the delegate", async() => { + it("Should successfully add the delegate", async() => { let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner}); assert.equal(tx.logs[0].args._delegate, account_delegate); }); diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index 4e2e80327..acc282ca2 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -382,7 +382,7 @@ contract("PreSaleSTO", accounts => { assert.equal( (await I_PolyToken.balanceOf(account_investor1)).toNumber(), initInvestorBalance.sub(value).toNumber(), - "tokens are not transfered out from investor account" + "tokens are not transferred out from investor account" ); assert.equal( (await I_PolyToken.balanceOf(token_owner)).toNumber(), From 4ce46668d73587daff14d8bd4766bc7f28c4c767 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Thu, 18 Oct 2018 19:47:27 +0530 Subject: [PATCH 140/142] Fixed withdraw recipient --- .../modules/Checkpoint/ERC20DividendCheckpoint.sol | 11 +++++++---- .../modules/Checkpoint/EtherDividendCheckpoint.sol | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol index 60d84a41b..6aa56c6ac 100644 --- a/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/ERC20DividendCheckpoint.sol @@ -1,6 +1,7 @@ pragma solidity ^0.4.24; import "./DividendCheckpoint.sol"; +import "../../interfaces/IOwnable.sol"; import "../../interfaces/IERC20.sol"; /** @@ -186,8 +187,9 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { dividends[_dividendIndex].reclaimed = true; Dividend storage dividend = dividends[_dividendIndex]; uint256 remainingAmount = dividend.amount.sub(dividend.claimedAmount); - require(IERC20(dividendTokens[_dividendIndex]).transfer(msg.sender, remainingAmount), "Unable to transfer tokens"); - emit ERC20DividendReclaimed(msg.sender, _dividendIndex, dividendTokens[_dividendIndex], remainingAmount); + address owner = IOwnable(securityToken).owner(); + require(IERC20(dividendTokens[_dividendIndex]).transfer(owner, remainingAmount), "Unable to transfer tokens"); + emit ERC20DividendReclaimed(owner, _dividendIndex, dividendTokens[_dividendIndex], remainingAmount); } /** @@ -199,8 +201,9 @@ contract ERC20DividendCheckpoint is DividendCheckpoint { Dividend storage dividend = dividends[_dividendIndex]; uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); dividend.dividendWithheldReclaimed = dividend.dividendWithheld; - require(IERC20(dividendTokens[_dividendIndex]).transfer(msg.sender, remainingWithheld), "Unable to transfer tokens"); - emit ERC20DividendWithholdingWithdrawn(msg.sender, _dividendIndex, dividendTokens[_dividendIndex], remainingWithheld); + address owner = IOwnable(securityToken).owner(); + require(IERC20(dividendTokens[_dividendIndex]).transfer(owner, remainingWithheld), "Unable to transfer tokens"); + emit ERC20DividendWithholdingWithdrawn(owner, _dividendIndex, dividendTokens[_dividendIndex], remainingWithheld); } } diff --git a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol index 0d5e3fbf2..94a9e79aa 100644 --- a/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/EtherDividendCheckpoint.sol @@ -1,6 +1,7 @@ pragma solidity ^0.4.24; import "./DividendCheckpoint.sol"; +import "../../interfaces/IOwnable.sol"; /** * @title Checkpoint module for issuing ether dividends @@ -163,8 +164,9 @@ contract EtherDividendCheckpoint is DividendCheckpoint { Dividend storage dividend = dividends[_dividendIndex]; dividend.reclaimed = true; uint256 remainingAmount = dividend.amount.sub(dividend.claimedAmount); - msg.sender.transfer(remainingAmount); - emit EtherDividendReclaimed(msg.sender, _dividendIndex, remainingAmount); + address owner = IOwnable(securityToken).owner(); + owner.transfer(remainingAmount); + emit EtherDividendReclaimed(owner, _dividendIndex, remainingAmount); } /** @@ -176,8 +178,9 @@ contract EtherDividendCheckpoint is DividendCheckpoint { Dividend storage dividend = dividends[_dividendIndex]; uint256 remainingWithheld = dividend.dividendWithheld.sub(dividend.dividendWithheldReclaimed); dividend.dividendWithheldReclaimed = dividend.dividendWithheld; - msg.sender.transfer(remainingWithheld); - emit EtherDividendWithholdingWithdrawn(msg.sender, _dividendIndex, remainingWithheld); + address owner = IOwnable(securityToken).owner(); + owner.transfer(remainingWithheld); + emit EtherDividendWithholdingWithdrawn(owner, _dividendIndex, remainingWithheld); } } From fa9c29b0f738a4287225fd006cfdabc88dc30caf Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 19 Oct 2018 11:41:53 +0530 Subject: [PATCH 141/142] Added function to deleteDelegate --- CHANGELOG.md | 1 + .../GeneralPermissionManager.sol | 58 +++++++++++++++---- .../PermissionManager/IPermissionManager.sol | 8 ++- test/g_general_permission_manager.js | 31 +++++++++- 4 files changed, 84 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4b8fdb42..35d0f98f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. [__1.5.0__](https://www.npmjs.com/package/polymath-core?activeTab=readme) __15-08-18__ ## Added +* Added `deleteDelegate()` to general permission manager. It will disable the delegate but not delete the perms. * Migrated from `npm` to `yarn`. * Added `SingleTradeVolumeRestrictionManager` module * Added flag in `PercentageTransferManager` to allow ignoring of issuance transfers diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 21c93f02b..85733ad21 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -8,7 +8,7 @@ import "../Module.sol"; */ contract GeneralPermissionManager is IPermissionManager, Module { - // Mapping used to hold the permissions on the modules provided to delegate, module add => delegate add => permission uint8 => bool + // Mapping used to hold the permissions on the modules provided to delegate, module add => delegate add => permission bytes32 => bool mapping (address => mapping (address => mapping (bytes32 => bool))) public perms; // Mapping hold the delagate details mapping (address => bytes32) public delegateDetails; @@ -59,6 +59,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { * @param _details Details about the delegate i.e `Belongs to financial firm` */ function addDelegate(address _delegate, bytes32 _details) external withPerm(CHANGE_PERMISSION) { + require(_delegate != address(0), "Invalid address"); require(_details != bytes32(0), "0 value not allowed"); require(delegateDetails[_delegate] == bytes32(0), "Already present"); delegateDetails[_delegate] = _details; @@ -66,6 +67,21 @@ contract GeneralPermissionManager is IPermissionManager, Module { emit AddDelegate(_delegate, _details, now); } + /** + * @notice Used to delete a delegate + * @param _delegate Ethereum address of the delegate + */ + function deleteDelegate(address _delegate) external withPerm(CHANGE_PERMISSION) { + require(delegateDetails[_delegate] != bytes32(0), "delegate does not exist"); + for (uint256 i = 0; i < allDelegates.length; i++) { + if (allDelegates[i] == _delegate) { + allDelegates[i] = allDelegates[allDelegates.length - 1]; + allDelegates.length = allDelegates.length - 1; + } + } + delete delegateDetails[_delegate]; + } + /** * @notice use to check if an address is a delegate or not * @param _potentialDelegate the address of potential delegate @@ -97,9 +113,8 @@ contract GeneralPermissionManager is IPermissionManager, Module { public withPerm(CHANGE_PERMISSION) { - require(delegateDetails[_delegate] != bytes32(0), "Delegate is not exists"); - perms[_module][_delegate][_perm] = _valid; - emit ChangePermission(_delegate, _module, _perm, _valid, now); + require(_delegate != address(0), "invalid address"); + _changePermission(_delegate, _module, _perm, _valid); } /** @@ -119,11 +134,12 @@ contract GeneralPermissionManager is IPermissionManager, Module { external withPerm(CHANGE_PERMISSION) { - require(_modules.length > 0 && _perms.length > 0, "0 length is not allowed"); + require(_delegate != address(0), "invalid address"); + require(_modules.length > 0, "0 length is not allowed"); require(_modules.length == _perms.length, "Array length mismatch"); require(_valids.length == _perms.length, "Array length mismatch"); - for(uint8 i = 0; i < _perms.length; i++) { - changePermission(_delegate, _modules[i], _perms[i], _valids[i]); + for(uint256 i = 0; i < _perms.length; i++) { + _changePermission(_delegate, _modules[i], _perms[i], _valids[i]); } } @@ -135,7 +151,7 @@ contract GeneralPermissionManager is IPermissionManager, Module { */ function getAllDelegatesWithPerm(address _module, bytes32 _perm) external view returns(address[]) { uint256 counter = 0; - uint8 i = 0; + uint256 i = 0; for (i = 0; i < allDelegates.length; i++) { if (perms[_module][allDelegates[i]][_perm]) { counter++; @@ -164,13 +180,13 @@ contract GeneralPermissionManager is IPermissionManager, Module { function getAllModulesAndPermsFromTypes(address _delegate, uint8[] _types, address _tokenAddress) external view returns(address[], bytes32[]) { uint256 counter = 0; // loop through _types and get their modules from securityToken->getModulesByType - for (uint8 i = 0; i < _types.length; i++) { + for (uint256 i = 0; i < _types.length; i++) { address[] memory _currentTypeModules = ISecurityToken(_tokenAddress).getModulesByType(_types[i]); // loop through each modules to get their perms from IModule->getPermissions - for (uint8 j = 0; j < _currentTypeModules.length; j++){ + for (uint256 j = 0; j < _currentTypeModules.length; j++){ bytes32[] memory _allModulePerms = IModule(_currentTypeModules[j]).getPermissions(); // loop through each perm, if it is true, push results into arrays - for (uint8 k = 0; k < _allModulePerms.length; k++) { + for (uint256 k = 0; k < _allModulePerms.length; k++) { if (perms[_currentTypeModules[j]][_delegate][_allModulePerms[k]]) { counter ++; } @@ -199,6 +215,26 @@ contract GeneralPermissionManager is IPermissionManager, Module { return(_allModules, _allPerms); } + /** + * @notice Use to provide/change the permission to the delegate corresponds to the module contract + * @param _delegate Ethereum address of the delegate + * @param _module Ethereum contract address of the module + * @param _perm Permission flag + * @param _valid Bool flag use to switch on/off the permission + * @return bool + */ + function _changePermission( + address _delegate, + address _module, + bytes32 _perm, + bool _valid + ) + internal + { + perms[_module][_delegate][_perm] = _valid; + emit ChangePermission(_delegate, _module, _perm, _valid, now); + } + /** * @notice use to get all delegates * @return address[] diff --git a/contracts/modules/PermissionManager/IPermissionManager.sol b/contracts/modules/PermissionManager/IPermissionManager.sol index 2b9c93ee8..00cea581c 100644 --- a/contracts/modules/PermissionManager/IPermissionManager.sol +++ b/contracts/modules/PermissionManager/IPermissionManager.sol @@ -14,13 +14,19 @@ interface IPermissionManager { */ function checkPermission(address _delegate, address _module, bytes32 _perm) external view returns(bool); - /** + /** * @notice Use to add a delegate * @param _delegate Ethereum address of the delegate * @param _details Details about the delegate i.e `Belongs to financial firm` */ function addDelegate(address _delegate, bytes32 _details) external; + /** + * @notice Used to delete a delegate + * @param _delegate Ethereum address of the delegate + */ + function deleteDelegate(address _delegate) external; + /** * @notice use to check if an address is a delegate or not * @param _potentialDelegate the address of potential delegate diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 231cefe70..376443f50 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -214,9 +214,15 @@ contract('GeneralPermissionManager', accounts => { ); }); - it("Should fail to provide the permission -- because delegate is not yet added", async() => { + it("Should fail in adding the delegate -- no delegate address provided", async() => { + catchRevert( + I_GeneralPermissionManager.addDelegate('', delegateDetails, { from: token_owner }) + ); + }); + + it("Should fail to remove the delegate -- failed because delegate does not exisit", async() => { await catchRevert( - I_GeneralPermissionManager.changePermission(account_delegate, I_GeneralTransferManager.address, "WHITELIST", true, {from: token_owner}) + I_GeneralPermissionManager.deleteDelegate(account_delegate, { from: token_owner}) ); }); @@ -260,6 +266,27 @@ contract('GeneralPermissionManager', accounts => { ); }); + it("Should fail to remove the delegate -- failed because unauthorized msg.sender", async() => { + await catchRevert( + I_GeneralPermissionManager.deleteDelegate(account_delegate, { from: account_delegate}) + ); + }); + + it("Should remove the delegate", async() => { + await I_GeneralPermissionManager.deleteDelegate(account_delegate, { from: token_owner}) + }); + + it("Should check the permission", async () => { + assert.isFalse( + await I_GeneralPermissionManager.checkPermission.call(account_delegate, I_GeneralTransferManager.address, "WHITELIST") + ); + }); + + it("Should successfully add the delegate", async() => { + let tx = await I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: token_owner}); + assert.equal(tx.logs[0].args._delegate, account_delegate); + }); + it("Should check the delegate details", async() => { assert.equal(web3.utils.toAscii(await I_GeneralPermissionManager.delegateDetails.call(account_delegate)) .replace(/\u0000/g, ''), From c9abbd5cf7a1a44a46af97cb3461b4efd89d2bb8 Mon Sep 17 00:00:00 2001 From: Mudit Gupta Date: Fri, 19 Oct 2018 12:13:59 +0530 Subject: [PATCH 142/142] Update g_general_permission_manager.js --- test/g_general_permission_manager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 376443f50..30632ab07 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -209,13 +209,13 @@ contract('GeneralPermissionManager', accounts => { }); it("Should fail in adding the delegate -- no delegate details provided", async() => { - catchRevert( + await catchRevert( I_GeneralPermissionManager.addDelegate(account_delegate, '', { from: token_owner }) ); }); it("Should fail in adding the delegate -- no delegate address provided", async() => { - catchRevert( + await catchRevert( I_GeneralPermissionManager.addDelegate('', delegateDetails, { from: token_owner }) ); });